PATCH (libstdc++-v3): Fix libstdc++/7680 (and a reference fix for the dynamic visibility of C99 features in system headers)

Loren James Rittle rittle@latour.rsch.comm.mot.com
Tue Apr 15 07:29:00 GMT 2003


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;
+ }



More information about the Gcc-patches mailing list