summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog8
-rw-r--r--math/Makefile4
-rw-r--r--math/bug-tgmath1.c33
-rw-r--r--math/tgmath.h37
4 files changed, 77 insertions, 5 deletions
diff --git a/ChangeLog b/ChangeLog
index 04f4aadbe7..ab752fcc62 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2004-05-06  Ulrich Drepper  <drepper@redhat.com>
+
+	* math/tgmath.h (__TGMATH_UNARY_REAL_IMAG_RET_REAL):Define.
+	(cimag): Use it.
+	(creal): Likewise.
+	* math/Makefile (tests): Add bug-tgmath1.
+	* math/bug-tgmath1.c: New file.
+
 2004-05-05  Jakub Jelinek  <jakub@redhat.com>
 
 	* sysdeps/alpha/atomicity.h: Remove.
diff --git a/math/Makefile b/math/Makefile
index 6a9134b5dd..c4501b87f4 100644
--- a/math/Makefile
+++ b/math/Makefile
@@ -1,4 +1,4 @@
-# Copyright (C) 1996-2001, 2002, 2003 Free Software Foundation, Inc.
+# Copyright (C) 1996-2001, 2002, 2003, 2004 Free Software Foundation, Inc.
 # This file is part of the GNU C Library.
 
 # The GNU C Library is free software; you can redistribute it and/or
@@ -89,7 +89,7 @@ distribute += $(filter-out $(generated),$(long-m-yes:=.c) $(long-c-yes:=.c))
 # Rules for the test suite.
 tests = test-matherr test-fenv atest-exp atest-sincos atest-exp2 basic-test \
 	test-misc test-fpucw tst-definitions test-tgmath test-tgmath-ret \
-	bug-nextafter bug-nexttoward
+	bug-nextafter bug-nexttoward bug-tgmath1
 # We do the `long double' tests only if this data type is available and
 # distinct from `double'.
 test-longdouble-yes = test-ldouble test-ildoubl
diff --git a/math/bug-tgmath1.c b/math/bug-tgmath1.c
new file mode 100644
index 0000000000..8a457fa252
--- /dev/null
+++ b/math/bug-tgmath1.c
@@ -0,0 +1,33 @@
+#include <stdio.h>
+#include <tgmath.h>
+
+
+int
+main (void)
+{
+  int retval = 0;
+
+#define TEST(expr, res) \
+  if (sizeof (expr) != res)						      \
+    {									      \
+      printf ("sizeof(%s) == %zu, expected %zu\n", #expr,		      \
+	      sizeof (expr), (size_t) (res));				      \
+      retval = 1;								      \
+    }
+
+  TEST (creal (1.0), sizeof (double));
+  TEST (creal (1.0 + 1.0i), sizeof (double));
+  TEST (creal (1.0l), sizeof (long double));
+  TEST (creal (1.0l + 1.0li), sizeof (long double));
+  TEST (creal (1.0f), sizeof (float));
+  TEST (creal (1.0f + 1.0fi), sizeof (float));
+
+  TEST (cimag (1.0), sizeof (double));
+  TEST (cimag (1.0 + 1.0i), sizeof (double));
+  TEST (cimag (1.0l), sizeof (long double));
+  TEST (cimag (1.0l + 1.0li), sizeof (long double));
+  TEST (cimag (1.0f), sizeof (float));
+  TEST (cimag (1.0f + 1.0fi), sizeof (float));
+
+  return retval;
+}
diff --git a/math/tgmath.h b/math/tgmath.h
index 168b262e68..0202e100bc 100644
--- a/math/tgmath.h
+++ b/math/tgmath.h
@@ -1,4 +1,5 @@
-/* Copyright (C) 1997, 1998, 1999, 2000, 2001, 2003 Free Software Foundation, Inc.
+/* Copyright (C) 1997, 1998, 1999, 2000, 2001, 2003, 2004
+   Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
@@ -177,6 +178,36 @@
 
 /* XXX This definition has to be changed as soon as the compiler understands
    the imaginary keyword.  */
+# define __TGMATH_UNARY_REAL_IMAG_RET_REAL(Val, Fct, Cfct) \
+     (__extension__ ({ __tgmath_real_type (Val) __tgmres;		      \
+		       if (sizeof (__real__ (Val)) > sizeof (double)	      \
+			   && __builtin_classify_type (__real__ (Val)) == 8)  \
+			 {						      \
+			   if (sizeof (__real__ (Val)) == sizeof (Val))	      \
+			     __tgmres = __tgml(Fct) (Val);		      \
+			   else						      \
+			     __tgmres = __tgml(Cfct) (Val);		      \
+			 }						      \
+		       else if (sizeof (__real__ (Val)) == sizeof (double)    \
+				|| __builtin_classify_type (__real__ (Val))   \
+				   != 8)				      \
+			 {						      \
+			   if (sizeof (__real__ (Val)) == sizeof (Val))	      \
+			     __tgmres = Fct (Val);			      \
+			   else						      \
+			     __tgmres = Cfct (Val);			      \
+			 }						      \
+		       else						      \
+			 {						      \
+			   if (sizeof (__real__ (Val)) == sizeof (Val))	      \
+			     __tgmres = Fct##f (Val);			      \
+			   else						      \
+			     __tgmres = Cfct##f (Val);			      \
+			 }						      \
+		       __real__ __tgmres; }))
+
+/* XXX This definition has to be changed as soon as the compiler understands
+   the imaginary keyword.  */
 # define __TGMATH_BINARY_REAL_IMAG(Val1, Val2, Fct, Cfct) \
      (__extension__ ({ __tgmath_real_type ((Val1) + (Val2)) __tgmres;	      \
 		       if ((sizeof (__real__ (Val1)) > sizeof (double)	      \
@@ -420,9 +451,9 @@
 /* Decomposing complex values.  */
 
 /* Imaginary part of Z.  */
-#define cimag(Val) __TGMATH_UNARY_REAL_IMAG (Val, cimag, cimag)
+#define cimag(Val) __TGMATH_UNARY_REAL_IMAG_RET_REAL (Val, cimag, cimag)
 
 /* Real part of Z.  */
-#define creal(Val) __TGMATH_UNARY_REAL_IMAG (Val, creal, creal)
+#define creal(Val) __TGMATH_UNARY_REAL_IMAG_RET_REAL (Val, creal, creal)
 
 #endif /* tgmath.h */