This is the mail archive of the libstdc++@sourceware.cygnus.com mailing list for the libstdc++ project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

(patch) Workaround for gcc's float complex bug.


GCC has buggy __complex__ float support on a variety of platforms (eg.,
all x86-win32 ports), and libstdc++ code tweaks one particular one. The
mainline may have it fixed, but egcs-1.1.x and gcc-2.95.x suffer from
it.

I've added a new macro, GLIBCPP_CHECK_FLOAT_COMPLEX_SUPPORT, that checks
for this bug and defines BUGGY_FLOAT_COMPLEX if so. The usage in
bits/std_complex.h and src/complex.cc is self-explanatory.

Note that I have not submitted diffs for autogenerated files in this
patch -- aclocal.m4, config.h.in and configure.
  
  $ aclocal -I m4
  $ autoheader
  $ autoconf

There are two more small tweaks for Cygwin and Mingw32 builds, and
I'll send those off in a day or two.

Sun Nov 21 23:34:04 1999  Mumit Khan  <khan@xraylith.wisc.edu>

	* acinclude.m4: New file. New GLIBCPP_CHECK_FLOAT_SUPPORT macro.
	* configure.in: Use.
	* acconfig.h: New BUGGY_FLOAT_COMPLEX macro.
	* src/complexf.cc: New FLOAT_SPECIALIZATION macro.
	* bits/std_complex.h: Use.
	* src/complex.cc: Use.

Index: acinclude.m4
===================================================================
RCS file: acinclude.m4
diff -N acinclude.m4
--- /dev/null	Tue May  5 15:32:27 1998
+++ acinclude.m4	Sun Nov 21 23:27:08 1999
@@ -0,0 +1,44 @@
+dnl
+dnl Check to see if this version of GNU C++ is afflicted by bugs in
+dnl __complex__ float support.
+dnl 
+dnl Define BUGGY_FLOAT_COMPLEX if buggy.
+dnl
+dnl GLIBCPP_CHECK_FLOAT_COMPLEX_SUPPORT
+AC_DEFUN(GLIBCPP_CHECK_FLOAT_COMPLEX_SUPPORT, [
+  AC_REQUIRE([AC_PROG_CXX])
+  AC_MSG_CHECKING([for GNU C++ float __complex__ support])
+  AC_CACHE_VAL(glibcpp_cv_float_complex, [
+    AC_LANG_SAVE
+    AC_LANG_CPLUSPLUS
+    rm -f conftest.h
+    cat > conftest.h <<EOB
+      //
+      // Check for buggy __complex__ that causes ICE in most versions of egcs
+      // and gcc-2.95.x on certain platforms (eg., x86-win32). 
+      //
+      // See http://egcs.cygnus.com/ml/gcc-bugs/1999-07/msg00845.html for 
+      // more info on the bug itself.
+      //
+      struct 
+      float_complex
+      {
+	__complex__ float m_value;
+	float_complex (float = 0.0f, float = 0.0f);
+	float_complex (__complex__ float val) : m_value (val) {}
+	float_complex foo (const float_complex &val)
+	  { return float_complex (~val.m_value); }
+      };
+EOB
+    AC_TRY_COMPILE([#include "conftest.h"], ,
+      glibcpp_cv_float_complex=ok,
+      glibcpp_cv_float_complex=buggy
+    )
+    AC_LANG_RESTORE
+  ])
+  AC_MSG_RESULT($glibcpp_cv_float_complex)
+  if test $glibcpp_cv_float_complex = buggy; then
+    AC_DEFINE(BUGGY_FLOAT_COMPLEX)
+  fi
+])
+
Index: configure.in
===================================================================
RCS file: /homes/khan/src/CVSROOT/libstdc++/configure.in,v
retrieving revision 1.1.1.1
diff -u -3 -p -r1.1.1.1 configure.in
--- configure.in	1999/11/22 05:21:25	1.1.1.1
+++ configure.in	1999/11/22 05:26:10
@@ -138,6 +138,8 @@ fi
 
 AC_LC_MESSAGES
 
+GLIBCPP_CHECK_FLOAT_COMPLEX_SUPPORT 
+
 AC_OUTPUT([bits/c++config.h Makefile math/Makefile string/Makefile libio/Makefile src/Makefile])
 
 # Generate bits/c++config.h
Index: acconfig.h
===================================================================
RCS file: /homes/khan/src/CVSROOT/libstdc++/acconfig.h,v
retrieving revision 1.1.1.1
diff -u -3 -p -r1.1.1.1 acconfig.h
--- acconfig.h	1999/11/22 05:21:25	1.1.1.1
+++ acconfig.h	1999/11/22 05:25:36
@@ -37,6 +37,9 @@
 // Define if the compiler/host combination has __builtin_fabsf defined.
 #undef _GLIBCPP_HAS_BUILTIN_SQRTF
 
+// Define if GCC support for __complex__ float is buggy.
+#undef BUGGY_FLOAT_COMPLEX
+
 // @BOTTOM@
 //
 // Systems that have certain non-standard functions prefixed with an
Index: bits/std_complex.h
===================================================================
RCS file: /homes/khan/src/CVSROOT/libstdc++/bits/std_complex.h,v
retrieving revision 1.1.1.1
diff -u -3 -p -r1.1.1.1 std_complex.h
--- std_complex.h	1999/11/22 05:21:26	1.1.1.1
+++ std_complex.h	1999/11/22 05:30:14
@@ -923,7 +923,14 @@ namespace std
     template<>
     inline complex<float>
     conj(const complex<float> &__x)
-    { return complex<float> (~__x._M_value); }
+#ifdef BUGGY_FLOAT_COMPLEX
+    { 
+      complex<float> __tmpf(~__x._M_value); 
+      return __tmpf; 
+    }
+#else
+    { return complex<float>(~__x._M_value); }
+#endif
 
     template<>
     inline complex<double>
Index: src/complex.cc
===================================================================
RCS file: /homes/khan/src/CVSROOT/libstdc++/src/complex.cc,v
retrieving revision 1.1.1.1
diff -u -3 -p -r1.1.1.1 complex.cc
--- complex.cc	1999/11/22 05:21:27	1.1.1.1
+++ complex.cc	1999/11/22 05:30:14
@@ -86,80 +86,184 @@ namespace std
       FCT(sincos)(__theta, &__sinx, &__cosx);
       return complex<FLT>(__rho * __cosx, __rho * __sinx);
 #else
+#if defined(BUGGY_FLOAT_COMPLEX) && defined(FLOAT_SPECIALIZATION)
+      complex<FLT> __tmpf(__rho * FCT(cos)(__theta), 
+		          __rho * FCT(sin)(__theta));
+      return __tmpf;
+#else
       return complex<FLT>(__rho * FCT(cos)(__theta), 
 			  __rho * FCT(sin)(__theta));
 #endif
+#endif
     }
 
     template<>
     complex<FLT>
     cos(const complex<FLT>& __x)
+#if defined(BUGGY_FLOAT_COMPLEX) && defined(FLOAT_SPECIALIZATION)
+    { 
+      complex<FLT> __tmpf(FCT(ccos)(__x._M_value));
+      return __tmpf;
+    }
+#else
     { return complex<FLT>(FCT(ccos)(__x._M_value)); }
+#endif
 
     template<>
     complex<FLT>
     cosh(const complex<FLT>& __x)
+#if defined(BUGGY_FLOAT_COMPLEX) && defined(FLOAT_SPECIALIZATION)
+    { 
+      complex<FLT> __tmpf(FCT(ccosh)(__x._M_value)); 
+      return __tmpf; 
+    }
+#else
     { return complex<FLT>(FCT(ccosh)(__x._M_value)); }
+#endif
 
     template<>
     complex<FLT>
     exp(const complex<FLT>& __x)
+#if defined(BUGGY_FLOAT_COMPLEX) && defined(FLOAT_SPECIALIZATION)
+    { 
+      complex<FLT> __tmpf(FCT(cexp)(__x._M_value));
+      return __tmpf; 
+    }
+#else
     { return complex<FLT>(FCT(cexp)(__x._M_value)); }
+#endif
 
     template<>
     complex<FLT>
     log(const complex<FLT>& __x)
+#if defined(BUGGY_FLOAT_COMPLEX) && defined(FLOAT_SPECIALIZATION)
+    { 
+      complex<FLT> __tmpf(FCT(c_log)(__x._M_value)); 
+      return __tmpf; 
+    }
+#else
     { return complex<FLT>(FCT(c_log)(__x._M_value)); }
+#endif
 
     template<>
     complex<FLT>
     log10(const complex<FLT>& __x)
+#if defined(BUGGY_FLOAT_COMPLEX) && defined(FLOAT_SPECIALIZATION)
+    { 
+      complex<FLT> __tmpf(FCT(clog10)(__x._M_value)); 
+      return __tmpf; 
+    }
+#else
     { return complex<FLT>(FCT(clog10)(__x._M_value)); }
+#endif
 
     template<>
     complex<FLT>
     pow(const complex<FLT>& __x, int __n)
+#if defined(BUGGY_FLOAT_COMPLEX) && defined(FLOAT_SPECIALIZATION)
+    { 
+      complex<FLT> __tmpf(FCT(cexp) (__n * FCT(c_log)(__x._M_value))); 
+      return __tmpf; 
+    }
+#else
     { return complex<FLT>(FCT(cexp) (__n * FCT(c_log)(__x._M_value))); }
+#endif
 
     template<>
     complex<FLT>
     pow(const complex<FLT>& __x, const FLT& __y)
+#if defined(BUGGY_FLOAT_COMPLEX) && defined(FLOAT_SPECIALIZATION)
+    { 
+      complex<FLT> __tmpf(FCT(cexp) (__y * FCT(c_log)(__x._M_value))); 
+      return __tmpf; 
+    }
+#else
     { return complex<FLT>(FCT(cexp) (__y * FCT(c_log)(__x._M_value))); }
+#endif
 
     template<>
     complex<FLT>
     pow(const complex<FLT>& __x, const complex<FLT>& __y)
+#if defined(BUGGY_FLOAT_COMPLEX) && defined(FLOAT_SPECIALIZATION)
+    { 
+      complex<FLT> __tmpf(FCT(cpow)(__x._M_value, __y._M_value)); 
+      return __tmpf; 
+    }
+#else
     { return complex<FLT>(FCT(cpow)(__x._M_value, __y._M_value)); }
+#endif
 
     template<>
     complex<FLT>
     pow(const FLT& __x, const complex<FLT>& __y)
+#if defined(BUGGY_FLOAT_COMPLEX) && defined(FLOAT_SPECIALIZATION)
+    { 
+      complex<FLT> __tmpf(FCT(cexp)(__y._M_value * FCT(log)(__x))); 
+      return __tmpf; 
+    }
+#else
     { return complex<FLT>(FCT(cexp)(__y._M_value * FCT(log)(__x))); }
+#endif
 
     template<>
     complex<FLT>
     sin(const complex<FLT>& __x)
+#if defined(BUGGY_FLOAT_COMPLEX) && defined(FLOAT_SPECIALIZATION)
+    { 
+      complex<FLT> __tmpf(FCT(csin)(__x._M_value)); 
+      return __tmpf; 
+    }
+#else
     { return complex<FLT>(FCT(csin)(__x._M_value)); }
+#endif
 
     template<>
     complex<FLT>
     sinh(const complex<FLT>& __x)
+#if defined(BUGGY_FLOAT_COMPLEX) && defined(FLOAT_SPECIALIZATION)
+    { 
+      complex<FLT> __tmpf(FCT(csinh)(__x._M_value)); 
+      return __tmpf; 
+    }
+#else
     { return complex<FLT>(FCT(csinh)(__x._M_value)); }
+#endif
 
     template<>
     complex<FLT>
     sqrt(const complex<FLT>& __x)
+#if defined(BUGGY_FLOAT_COMPLEX) && defined(FLOAT_SPECIALIZATION)
+    { 
+      complex<FLT> __tmpf(FCT(csqrt)(__x._M_value));  
+      return __tmpf; 
+    }
+#else
     { return complex<FLT>(FCT(csqrt)(__x._M_value)); }
+#endif
 
     template<>
     complex<FLT>
     tan(const complex<FLT>& __x)
+#if defined(BUGGY_FLOAT_COMPLEX) && defined(FLOAT_SPECIALIZATION)
+    { 
+      complex<FLT> __tmpf(FCT(ctan)(__x._M_value)); 
+      return __tmpf; 
+    }
+#else
     { return complex<FLT>(FCT(ctan)(__x._M_value)); }
+#endif
 
     template<>
     complex<FLT>
     tanh(const complex<FLT>& __x)
+#if defined(BUGGY_FLOAT_COMPLEX) && defined(FLOAT_SPECIALIZATION)
+    { 
+      complex<FLT> __tmpf(FCT(ctanh)(__x._M_value)); 
+      return __tmpf; 
+    }
+#else
     { return complex<FLT>(FCT(ctanh)(__x._M_value)); }
+#endif
     
 } // namespace std
 
Index: src/complexf.cc
===================================================================
RCS file: /homes/khan/src/CVSROOT/libstdc++/src/complexf.cc,v
retrieving revision 1.1.1.1
diff -u -3 -p -r1.1.1.1 complexf.cc
--- complexf.cc	1999/11/22 05:21:27	1.1.1.1
+++ complexf.cc	1999/11/22 05:31:47
@@ -1,3 +1,5 @@
 #define FLT float
 #define FCT(name) name##f
+// Used in complex.cc to work around GCC's buggy __complex__ float support.
+#define FLOAT_SPECIALIZATION 1
 #include "complex.cc"

Regards,
Mumit


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]