This is the mail archive of the
libstdc++@sourceware.cygnus.com
mailing list for the libstdc++ project.
(patch) Workaround for gcc's float complex bug.
- To: libstdc++ at sourceware dot cygnus dot com
- Subject: (patch) Workaround for gcc's float complex bug.
- From: Mumit Khan <khan at nanotech dot wisc dot edu>
- Date: Mon, 22 Nov 1999 00:09:55 -0600
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