This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
PATCH (libstdc++-v3): Fix libstdc++/7680 (and a reference fix for the dynamic visibility of C99 features in system headers)
- From: Loren James Rittle <rittle at latour dot rsch dot comm dot mot dot com>
- To: libstdc++ at gcc dot gnu dot org
- Cc: imp at bsdimp dot com, gcc-patches at gcc dot gnu dot org
- Date: Tue, 15 Apr 2003 02:29:20 -0500 (CDT)
- Subject: PATCH (libstdc++-v3): Fix libstdc++/7680 (and a reference fix for the dynamic visibility of C99 features in system headers)
- References: <200304120925.h3C9PNrk050805@latour.rsch.comm.mot.com>
- Reply-to: rittle at labs dot mot dot com
As applied. I changed the namespace usage to conform to the collective
list feedback. Also, before committing, I noticed that I had to guard
every blasted using ::X statement independently. Rebuilt libstdc++-v3
tree on i386-unknown-freebsd4.8, checked without regression.
libstdc++/7680
* include/c_std/std_cmath.h (__gnu_cx::__c99_binding): New namespace.
Populate it with multiple legal ways to obtain the C99 float
transcendentals. Use them instead of direct global reference.
(C99 FP capture): Guard usage with _GLIBCPP_USE_C99_FP_MACROS_DYNAMIC.
* docs/html/17_intro/porting.texi
(_GLIBCPP_USE_C99_FLOAT_TRANSCENDENTALS_CHECK): New macro.
(_GLIBCPP_USE_C99_FLOAT_TRANSCENDENTALS_DYNAMIC): New macro.
(_GLIBCPP_USE_C99_FP_MACROS_DYNAMIC): New macro.
* config/os/bsd/freebsd/os_defines.h
(_GLIBCPP_USE_C99_FLOAT_TRANSCENDENTALS_CHECK): New macro.
(_GLIBCPP_USE_C99_FLOAT_TRANSCENDENTALS_DYNAMIC): New macro.
* testsuite/26_numerics/c_math_dynamic.cc: New file.
Index: include/c_std/std_cmath.h
===================================================================
RCS file: /cvs/gcc/gcc/libstdc++-v3/include/c_std/std_cmath.h,v
retrieving revision 1.6
diff -c -r1.6 std_cmath.h
*** include/c_std/std_cmath.h 21 Jun 2002 20:20:48 -0000 1.6
--- include/c_std/std_cmath.h 15 Apr 2003 07:23:45 -0000
***************
*** 1,6 ****
// -*- C++ -*- C forwarding header.
! // Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002
// Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
--- 1,6 ----
// -*- C++ -*- C forwarding header.
! // Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003
// Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
***************
*** 76,81 ****
--- 76,166 ----
#undef tan
#undef tanh
+ // ...and in the darkness bind them...
+ namespace __gnu_cxx
+ {
+ namespace __c99_binding
+ {
+ #if _GLIBCPP_USE_C99_FLOAT_TRANSCENDENTALS_CHECK || \
+ _GLIBCPP_USE_C99_FLOAT_TRANSCENDENTALS_DYNAMIC
+ extern "C" float (acosf)(float);
+ extern "C" float (asinf)(float);
+ extern "C" float (atanf)(float);
+ extern "C" float (atan2f)(float, float);
+ extern "C" float (ceilf)(float);
+ extern "C" float (coshf)(float);
+ extern "C" float (expf)(float);
+ extern "C" float (floorf)(float);
+ extern "C" float (fmodf)(float, float);
+ extern "C" float (frexpf)(float, int*);
+ extern "C" float (ldexpf)(float, int);
+ extern "C" float (logf)(float);
+ extern "C" float (log10f)(float);
+ extern "C" float (modff)(float, float*);
+ extern "C" float (powf)(float, float);
+ extern "C" float (sinhf)(float);
+ extern "C" float (tanf)(float);
+ extern "C" float (tanhf)(float);
+ #endif
+ #if !_GLIBCPP_USE_C99_FLOAT_TRANSCENDENTALS_DYNAMIC
+ #if _GLIBCPP_HAVE_ACOSF
+ using ::acosf;
+ #endif
+ #if _GLIBCPP_HAVE_ASINF
+ using ::asinf;
+ #endif
+ #if _GLIBCPP_HAVE_ATANF
+ using ::atanf;
+ #endif
+ #if _GLIBCPP_HAVE_ATAN2F
+ using ::atan2f;
+ #endif
+ #if _GLIBCPP_HAVE_CEILF
+ using ::ceilf;
+ #endif
+ #if _GLIBCPP_HAVE_COSHF
+ using ::coshf;
+ #endif
+ #if _GLIBCPP_HAVE_EXPF
+ using ::expf;
+ #endif
+ #if _GLIBCPP_HAVE_FLOORF
+ using ::floorf;
+ #endif
+ #if _GLIBCPP_HAVE_FMODF
+ using ::fmodf;
+ #endif
+ #if _GLIBCPP_HAVE_FREXPF
+ using ::frexpf;
+ #endif
+ #if _GLIBCPP_HAVE_LDEXPF
+ using ::ldexpf;
+ #endif
+ #if _GLIBCPP_HAVE_LOGF
+ using ::logf;
+ #endif
+ #if _GLIBCPP_HAVE_LOG10F
+ using ::log10f;
+ #endif
+ #if _GLIBCPP_HAVE_MODFF
+ using ::modff;
+ #endif
+ #if _GLIBCPP_HAVE_POWF
+ using ::powf;
+ #endif
+ #if _GLIBCPP_HAVE_SINHF
+ using ::sinhf;
+ #endif
+ #if _GLIBCPP_HAVE_TANF
+ using ::tanf;
+ #endif
+ #if _GLIBCPP_HAVE_TANHF
+ using ::tanhf;
+ #endif
+ #endif /* _GLIBCPP_USE_C99_FLOAT_TRANSCENDENTALS_DYNAMIC */
+ }
+ }
+
namespace std
{
// Forward declaration of a helper function. This really should be
***************
*** 96,102 ****
#if _GLIBCPP_HAVE_ACOSF
inline float
! acos(float __x) { return ::acosf(__x); }
#else
inline float
acos(float __x) { return ::acos(static_cast<double>(__x)); }
--- 181,187 ----
#if _GLIBCPP_HAVE_ACOSF
inline float
! acos(float __x) { return __gnu_cxx::__c99_binding::acosf(__x); }
#else
inline float
acos(float __x) { return ::acos(static_cast<double>(__x)); }
***************
*** 116,122 ****
#if _GLIBCPP_HAVE_ASINF
inline float
! asin(float __x) { return ::asinf(__x); }
#else
inline float
asin(float __x) { return ::asin(static_cast<double>(__x)); }
--- 201,207 ----
#if _GLIBCPP_HAVE_ASINF
inline float
! asin(float __x) { return __gnu_cxx::__c99_binding::asinf(__x); }
#else
inline float
asin(float __x) { return ::asin(static_cast<double>(__x)); }
***************
*** 134,140 ****
#if _GLIBCPP_HAVE_ATANF
inline float
! atan(float __x) { return ::atanf(__x); }
#else
inline float
atan(float __x) { return ::atan(static_cast<double>(__x)); }
--- 219,225 ----
#if _GLIBCPP_HAVE_ATANF
inline float
! atan(float __x) { return __gnu_cxx::__c99_binding::atanf(__x); }
#else
inline float
atan(float __x) { return ::atan(static_cast<double>(__x)); }
***************
*** 152,158 ****
#if _GLIBCPP_HAVE_ATAN2F
inline float
! atan2(float __y, float __x) { return ::atan2f(__y, __x); }
#else
inline float
atan2(float __y, float __x)
--- 237,243 ----
#if _GLIBCPP_HAVE_ATAN2F
inline float
! atan2(float __y, float __x) { return __gnu_cxx::__c99_binding::atan2f(__y, __x); }
#else
inline float
atan2(float __y, float __x)
***************
*** 172,178 ****
#if _GLIBCPP_HAVE_CEILF
inline float
! ceil(float __x) { return ::ceilf(__x); }
#else
inline float
ceil(float __x) { return ::ceil(static_cast<double>(__x)); }
--- 257,263 ----
#if _GLIBCPP_HAVE_CEILF
inline float
! ceil(float __x) { return __gnu_cxx::__c99_binding::ceilf(__x); }
#else
inline float
ceil(float __x) { return ::ceil(static_cast<double>(__x)); }
***************
*** 200,206 ****
#if _GLIBCPP_HAVE_COSHF
inline float
! cosh(float __x) { return ::coshf(__x); }
#else
inline float
cosh(float __x) { return ::cosh(static_cast<double>(__x)); }
--- 285,291 ----
#if _GLIBCPP_HAVE_COSHF
inline float
! cosh(float __x) { return __gnu_cxx::__c99_binding::coshf(__x); }
#else
inline float
cosh(float __x) { return ::cosh(static_cast<double>(__x)); }
***************
*** 218,224 ****
#if _GLIBCPP_HAVE_EXPF
inline float
! exp(float __x) { return ::expf(__x); }
#else
inline float
exp(float __x) { return ::exp(static_cast<double>(__x)); }
--- 303,309 ----
#if _GLIBCPP_HAVE_EXPF
inline float
! exp(float __x) { return __gnu_cxx::__c99_binding::expf(__x); }
#else
inline float
exp(float __x) { return ::exp(static_cast<double>(__x)); }
***************
*** 246,252 ****
#if _GLIBCPP_HAVE_FLOORF
inline float
! floor(float __x) { return ::floorf(__x); }
#else
inline float
floor(float __x) { return ::floor(static_cast<double>(__x)); }
--- 331,337 ----
#if _GLIBCPP_HAVE_FLOORF
inline float
! floor(float __x) { return __gnu_cxx::__c99_binding::floorf(__x); }
#else
inline float
floor(float __x) { return ::floor(static_cast<double>(__x)); }
***************
*** 264,270 ****
#if _GLIBCPP_HAVE_FMODF
inline float
! fmod(float __x, float __y) { return ::fmodf(__x, __y); }
#else
inline float
fmod(float __x, float __y)
--- 349,355 ----
#if _GLIBCPP_HAVE_FMODF
inline float
! fmod(float __x, float __y) { return __gnu_cxx::__c99_binding::fmodf(__x, __y); }
#else
inline float
fmod(float __x, float __y)
***************
*** 284,290 ****
#if _GLIBCPP_HAVE_FREXPF
inline float
! frexp(float __x, int* __exp) { return ::frexpf(__x, __exp); }
#else
inline float
frexp(float __x, int* __exp) { return ::frexp(__x, __exp); }
--- 369,375 ----
#if _GLIBCPP_HAVE_FREXPF
inline float
! frexp(float __x, int* __exp) { return __gnu_cxx::__c99_binding::frexpf(__x, __exp); }
#else
inline float
frexp(float __x, int* __exp) { return ::frexp(__x, __exp); }
***************
*** 303,309 ****
#if _GLIBCPP_HAVE_LDEXPF
inline float
! ldexp(float __x, int __exp) { return ::ldexpf(__x, __exp); }
#else
inline float
ldexp(float __x, int __exp)
--- 388,394 ----
#if _GLIBCPP_HAVE_LDEXPF
inline float
! ldexp(float __x, int __exp) { return __gnu_cxx::__c99_binding::ldexpf(__x, __exp); }
#else
inline float
ldexp(float __x, int __exp)
***************
*** 323,329 ****
#if _GLIBCPP_HAVE_LOGF
inline float
! log(float __x) { return ::logf(__x); }
#else
inline float log(float __x)
{ return ::log(static_cast<double>(__x)); }
--- 408,414 ----
#if _GLIBCPP_HAVE_LOGF
inline float
! log(float __x) { return __gnu_cxx::__c99_binding::logf(__x); }
#else
inline float log(float __x)
{ return ::log(static_cast<double>(__x)); }
***************
*** 341,347 ****
#if _GLIBCPP_HAVE_LOG10F
inline float
! log10(float __x) { return ::log10f(__x); }
#else
inline float
log10(float __x) { return ::log10(static_cast<double>(__x)); }
--- 426,432 ----
#if _GLIBCPP_HAVE_LOG10F
inline float
! log10(float __x) { return __gnu_cxx::__c99_binding::log10f(__x); }
#else
inline float
log10(float __x) { return ::log10(static_cast<double>(__x)); }
***************
*** 359,365 ****
#if _GLIBCPP_HAVE_MODFF
inline float
! modf(float __x, float* __iptr) { return ::modff(__x, __iptr); }
#else
inline float
modf(float __x, float* __iptr)
--- 444,450 ----
#if _GLIBCPP_HAVE_MODFF
inline float
! modf(float __x, float* __iptr) { return __gnu_cxx::__c99_binding::modff(__x, __iptr); }
#else
inline float
modf(float __x, float* __iptr)
***************
*** 398,404 ****
#if _GLIBCPP_HAVE_POWF
inline float
! pow(float __x, float __y) { return ::powf(__x, __y); }
#else
inline float
pow(float __x, float __y)
--- 483,489 ----
#if _GLIBCPP_HAVE_POWF
inline float
! pow(float __x, float __y) { return __gnu_cxx::__c99_binding::powf(__x, __y); }
#else
inline float
pow(float __x, float __y)
***************
*** 440,446 ****
#if _GLIBCPP_HAVE_SINHF
inline float
! sinh(float __x) { return ::sinhf(__x); }
#else
inline float
sinh(float __x) { return ::sinh(static_cast<double>(__x)); }
--- 525,531 ----
#if _GLIBCPP_HAVE_SINHF
inline float
! sinh(float __x) { return __gnu_cxx::__c99_binding::sinhf(__x); }
#else
inline float
sinh(float __x) { return ::sinh(static_cast<double>(__x)); }
***************
*** 468,474 ****
#if _GLIBCPP_HAVE_TANF
inline float
! tan(float __x) { return ::tanf(__x); }
#else
inline float
tan(float __x) { return ::tan(static_cast<double>(__x)); }
--- 553,559 ----
#if _GLIBCPP_HAVE_TANF
inline float
! tan(float __x) { return __gnu_cxx::__c99_binding::tanf(__x); }
#else
inline float
tan(float __x) { return ::tan(static_cast<double>(__x)); }
***************
*** 486,492 ****
#if _GLIBCPP_HAVE_TANHF
inline float
! tanh(float __x) { return ::tanhf(__x); }
#else
inline float
tanh(float __x) { return ::tanh(static_cast<double>(__x)); }
--- 571,577 ----
#if _GLIBCPP_HAVE_TANHF
inline float
! tanh(float __x) { return __gnu_cxx::__c99_binding::tanhf(__x); }
#else
inline float
tanh(float __x) { return ::tanh(static_cast<double>(__x)); }
***************
*** 503,508 ****
--- 588,594 ----
#if _GLIBCPP_USE_C99
+ #if !_GLIBCPP_USE_C99_FP_MACROS_DYNAMIC
// These are possible macros imported from C99-land. For strict
// conformance, remove possible C99-injected names from the global
// namespace, and sequester them in the __gnu_cxx extension namespace.
***************
*** 561,566 ****
--- 647,653 ----
__capture_isunordered(_Tp __f1, _Tp __f2)
{ return isunordered(__f1, __f2); }
}
+ #endif /* _GLIBCPP_USE_C99_FP_MACROS_DYNAMIC */
#endif
#undef fpclassify
***************
*** 577,582 ****
--- 664,670 ----
#undef isunordered
#if _GLIBCPP_USE_C99
+ #if !_GLIBCPP_USE_C99_FP_MACROS_DYNAMIC
namespace __gnu_cxx
{
template<typename _Tp>
***************
*** 647,652 ****
--- 735,741 ----
using __gnu_cxx::islessgreater;
using __gnu_cxx::isunordered;
}
+ #endif /* _GLIBCPP_USE_C99_FP_MACROS_DYNAMIC */
#endif
#ifdef _GLIBCPP_NO_TEMPLATE_EXPORT
Index: docs/html/17_intro/porting.texi
===================================================================
RCS file: /cvs/gcc/gcc/libstdc++-v3/docs/html/17_intro/porting.texi,v
retrieving revision 1.9
diff -c -r1.9 porting.texi
*** docs/html/17_intro/porting.texi 4 Feb 2003 01:27:52 -0000 1.9
--- docs/html/17_intro/porting.texi 15 Apr 2003 07:23:45 -0000
***************
*** 150,160 ****
target. It will not work to simply define these macros in
@file{os_defines.h}.
! At this time, there is one libstdc++-v3-specific macro which may be
defined. @code{_G_USING_THUNKS} may be defined to 0 to express that the
port doesn't use thunks (although it is unclear that this is still
useful since libio support isn't currently working and the g++ v3 ABI
invalidates the assumption that some ports don't use thunks).
Finally, you should bracket the entire file in an include-guard, like
this:
--- 150,175 ----
target. It will not work to simply define these macros in
@file{os_defines.h}.
! At this time, there are a few libstdc++-v3-specific macro which may be
defined. @code{_G_USING_THUNKS} may be defined to 0 to express that the
port doesn't use thunks (although it is unclear that this is still
useful since libio support isn't currently working and the g++ v3 ABI
invalidates the assumption that some ports don't use thunks).
+
+ @code{_GLIBCPP_USE_C99_FP_MACROS_DYNAMIC} may be defined to an
+ expression that yields 0 if and only if the system headers
+ are exposing proper support for the related set of macros. If defined,
+ it must be 0 while bootstrapping the compiler/rebuilding the library.
+
+ @code{_GLIBCPP_USE_C99_FLOAT_TRANSCENDENTALS_CHECK} may be defined
+ to 1 to check the related set of function declarations found in system
+ headers against versions found in the library headers derived from
+ the standard.
+
+ @code{_GLIBCPP_USE_C99_FLOAT_TRANSCENDENTALS_DYNAMIC} may be defined
+ to an expression that yields 0 if and only if the system headers
+ are exposing proper support for the related set of functions. If defined,
+ it must be 0 while bootstrapping the compiler/rebuilding the library.
Finally, you should bracket the entire file in an include-guard, like
this:
Index: config/os/bsd/freebsd/os_defines.h
===================================================================
RCS file: /cvs/gcc/gcc/libstdc++-v3/config/os/bsd/freebsd/os_defines.h,v
retrieving revision 1.2
diff -c -r1.2 os_defines.h
*** config/os/bsd/freebsd/os_defines.h 26 Sep 2002 05:25:10 -0000 1.2
--- config/os/bsd/freebsd/os_defines.h 15 Apr 2003 07:23:45 -0000
***************
*** 34,37 ****
--- 34,40 ----
// System-specific #define, typedefs, corrections, etc, go here. This
// file will come before all others.
+ #define _GLIBCPP_USE_C99_FLOAT_TRANSCENDENTALS_CHECK 1
+ #define _GLIBCPP_USE_C99_FLOAT_TRANSCENDENTALS_DYNAMIC defined _XOPEN_SOURCE
+
#endif
Index: testsuite/26_numerics/c_math_dynamic.cc
===================================================================
RCS file: testsuite/26_numerics/c_math_dynamic.cc
diff -N testsuite/26_numerics/c_math_dynamic.cc
*** /dev/null 1 Jan 1970 00:00:00 -0000
--- testsuite/26_numerics/c_math_dynamic.cc 15 Apr 2003 07:23:45 -0000
***************
*** 0 ****
--- 1,58 ----
+ // Inspired by libstdc++/7680 & 26_numerics/c_math.cc, 2003-04-12 ljr
+
+ // Copyright (C) 2003 Free Software Foundation, Inc.
+ //
+ // This file is part of the GNU ISO C++ Library. This library is free
+ // software; you can redistribute it and/or modify it under the
+ // terms of the GNU General Public License as published by the
+ // Free Software Foundation; either version 2, or (at your option)
+ // any later version.
+
+ // This library is distributed in the hope that it will be useful,
+ // but WITHOUT ANY WARRANTY; without even the implied warranty of
+ // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ // GNU General Public License for more details.
+
+ // You should have received a copy of the GNU General Public License along
+ // with this library; see the file COPYING. If not, write to the Free
+ // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+ // USA.
+
+ // As a special exception, you may use this file as part of a free software
+ // library without restriction. Specifically, if other files instantiate
+ // templates or use macros or inline functions from this file, or you compile
+ // this file and link it with other files to produce an executable, this
+ // file does not by itself cause the resulting executable to be covered by
+ // the GNU General Public License. This exception does not however
+ // invalidate any other reasons why the executable file might be covered by
+ // the GNU General Public License.
+
+ // { dg-do link }
+ // { dg-options "-D_XOPEN_SOURCE" { target *-*-freebsd* } }
+
+ #include <cmath>
+
+ int
+ test01()
+ {
+ float a = 1.f;
+ float b;
+ std::modf(a, &b);
+ return 0;
+ }
+
+ int
+ test02 ()
+ {
+ float a = 0.0f;
+ float b = std::acos(b);
+ return 0;
+ }
+
+ int
+ main()
+ {
+ test01();
+ test02();
+ return 0;
+ }