diff mbox

[fixincludes,v3] Don't define libstdc++-internal macros in Solaris 10+ <math.h>

Message ID yddy410lkld.fsf@CeBiTec.Uni-Bielefeld.DE
State Superseded
Headers show

Commit Message

Rainer Orth Nov. 3, 2016, 2:11 p.m. UTC
As I've noticed some time ago, recent versions of Solaris <math.h>
include this little gem:

#if __cplusplus >= 201103L
#undef  _GLIBCXX_USE_C99_MATH
#undef  _GLIBCXX_USE_C99_MATH_TR1
#endif

This renders a couple of perfectly good libstdc++ tests as UNSUPPORTED
and is completely unsustainable.  Agreement has now been reached with
the Solaris libm maintainers that this wasn't a good idea and the plan
is to do away with it at least in future Solaris 11.3 SRUs and Solaris 12.

Some digging discovered that we have 3 levels of support in <math.h> and
<iso/math_c99.h:

1) No C++11 math support at all.

2) Overloads for C++11 math functions, already handled by

	[v3] Handle C++11 <math.h> overloads on Solaris 12
        https://gcc.gnu.org/ml/gcc-patches/2015-11/msg02075.html

   and the 4.9 backport

	[v3, 4.9] Handle C++11 <math.h> overloads on Solaris 11, 12
        https://gcc.gnu.org/ml/gcc-patches/2016-02/msg01477.html

   They were introduced in Solaris 10 Patch 11996[67]-02, Solaris 11.3
   SRU 3.6, and Solaris 12 Build 86.

3) Full C++11 math support, including the templates present in libstdc++
   <cmath>, and the #undef's above.

   Introduced in the same Solaris 10 Patch, Solaris 11.3 SRU 5.6, and
   Solaris 12 Build 90.

To check for potential fallout, I've added a fixincludes fix to remove
the #undefs.  As expected, there was quite a bit, e.g.

+FAIL: 25_algorithms/pop_heap/complexity.cc (test for excess errors)
+WARNING: 25_algorithms/pop_heap/complexity.cc compilation failed to produce executable

/vol/gcc/src/hg/trunk/local/libstdc++-v3/testsuite/25_algorithms/pop_heap/complexity.cc:48: error: call of overloaded 'log2(const size_t&)' is ambiguous

In file included from /var/gcc/regression/trunk/12-gcc/build/gcc/include-fixed/math.h:25,
                 from /var/gcc/regression/trunk/12-gcc/build/i386-pc-solaris2.12/libstdc++-v3/include/cmath:45,
                 from /vol/gcc/src/hg/trunk/local/libstdc++-v3/include/precompiled/stdc++.h:41:
/usr/include/iso/math_c99.h:474: note: candidate: double std::log2(double)
In file included from /var/gcc/regression/trunk/12-gcc/build/gcc/include-fixed/math.h:25,
                 from /var/gcc/regression/trunk/12-gcc/build/i386-pc-solaris2.12/libstdc++-v3/include/cmath:45,
                 from /vol/gcc/src/hg/trunk/local/libstdc++-v3/include/precompiled/stdc++.h:41:
/usr/include/iso/math_c99.h:763: note: candidate: float std::log2(float)
/usr/include/iso/math_c99.h:805: note: candidate: long double std::log2(long double)
/usr/include/iso/math_c99.h:946: note: candidate: typename std::__math_impl::__enable_if<std::__math_impl::__is_integral< <template-parameter-1-1> >::__value, double>::__type std::log2(_Tp) [with _Tp = unsigned int; typename std::__math_impl::__enable_if<std::__math_impl::__is_integral< <template-parameter-1-1> >::__value, double>::__type = double]
In file included from /vol/gcc/src/hg/trunk/local/libstdc++-v3/include/precompiled/stdc++.h:41:
/var/gcc/regression/trunk/12-gcc/build/i386-pc-solaris2.12/libstdc++-v3/include/cmath:1530: note: candidate: constexpr typename __gnu_cxx::__enable_if<std::__is_integer<_Tp>::__value, double>::__type std::log2(_Tp) [with _Tp = unsigned int; typename __gnu_cxx::__enable_if<std::__is_integer<_Tp>::__value, double>::__type = double]

due to duplicate log2 templates in <iso/math_c99.h> and c_global/cmath,
and many more of the same kind.

Fortunately, this is all easily fixed by wrapping the affected templates
in a new macro.  That's what this patch does.  The new libstdc++
acinclude.m4 test may well need wording changes in comments etc. and can
perhaps be shortened a bit, bit it worked for me.

The fixincludes part passes make check.

The patch has been regtested (C++ only) on

* Solaris 11.2 SRU 13.6 (i.e. without both overloads and templates in
  <iso/math_c99.h>),

* Solaris 11.3 SRU 3.6 (i.e. with overloads only), and

* Solaris 12 Build 110 (i.e. with both overloads and templates, and the
  _GLIBCXX_USE_C99_MATH #undef's)

* Linux/x86_64

I've checked that __CORRECT_ISO_CPP11_MATH_H_PROTO[12] were defined in
config.h as expected, and there were no testsuite regressions.  On the
contrary, a couple of tests that before showed up as UNSUPPORTED due to
the _GLIBCXX_USE_C99_MATH* #undef's now PASS as they should.

Ok for mainline now, and for backports to the gcc-6 and gcc-5 branches
after some soak time?

Thanks.
        Rainer

-- 
-----------------------------------------------------------------------------
Rainer Orth, Center for Biotechnology, Bielefeld University


2016-10-27  Rainer Orth  <ro@CeBiTec.Uni-Bielefeld.DE>

	libstdc++-v3:
	* acinclude.m4 (GLIBCXX_CHECK_MATH11_PROTO): Update comments.
	(__CORRECT_ISO_CPP11_MATH_H_PROTO): Rename to ...
	(__CORRECT_ISO_CPP11_MATH_H_PROTO1): ... this.
	Add test for C++11 <math.h> templates.
	* configure: Regenerate.
	* config.h.in: Regenerate.

	* include/c_global/cmath [__cplusplus >= 201103L]: Reflect
	__CORRECT_ISO_CPP11_MATH_H_PROTO to
	__CORRECT_ISO_CPP11_MATH_H_PROTO1 rename.
	* include/c_global/cmath [_GLIBCXX_USE_C99_MATH &&
	!_GLIBCXX_USE_C99_FP_MACROS_DYNAMIC && __cplusplus >= 201103L]
	(std::fpclassify): Wrap in !__CORRECT_ISO_CPP11_MATH_H_PROTO2.
	(std::isfinite): Likewise.
	(std::isinf): Likewise.
	(std::isnan): Likewise.
	(std::isnormal): Likewise.
	(std::signbit): Likewise.
	(std::isgreater): Likewise.
	(std::isgreaterequal): Likewise.
	(std::isless): Likewise.
	(std::islessequal): Likewise.
	(std::islessgreater): Likewise.
	(std::isunordered): Likewise.
	[__cplusplus >= 201103L && _GLIBCXX_USE_C99_MATH_TR1]
	(std::acosh): Likewise.
	(std::asinh): Likewise.
	(std::atanh): Likewise.
	(std::cbrt): Likewise.
	(std::copysign): Likewise.
	(std::erf): Likewise.
	(std::erfc): Likewise.
	(std::exp2): Likewise.
	(std::expm1): Likewise.
	(std::fdim): Likewise.
	(std::fma): Likewise.
	(std::fmax): Likewise.
	(std::fmin): Likewise.
	(std::hypot): Likewise.
	(std::ilogb): Likewise.
	(std::lgamma): Likewise.
	(std::llrint): Likewise.
	(std::llround): Likewise.
	(std::log1p): Likewise.
	(std::log2): Likewise.
	(std::logb): Likewise.
	(std::lrint): Likewise.
	(std::lround): Likewise.
	(std::nearbyint): Likewise.
	(std::nextafter): Likewise.
	(std::nexttoward): Likewise.
	(std::remainder): Likewise.
	(std::remquo): Likewise.
	(std::rint): Likewise.
	(std::round): Likewise.
	(std::scalbln): Likewise.
	(std::scalbn): Likewise.
	(std::tgamma): Likewise.
	(std::trunc): Likewise.
	* include/tr1/cmath [_GLIBCXX_USE_C99_MATH_TR1 && __cplusplus >=
	201103L]: Reflect __CORRECT_ISO_CPP11_MATH_H_PROTO to
	__CORRECT_ISO_CPP11_MATH_H_PROTO1 rename.

	fixincludes:
	* inclhack.def (solaris_math_12): New fix.
	* fixincl.x: Regenerate.
	* tests/base/math.h [SOLARIS_MATH_12_CHECK]: New test.

Comments

Bruce Korb Nov. 3, 2016, 7:45 p.m. UTC | #1
On 11/03/16 07:11, Rainer Orth wrote:
>

> Ok for mainline now, and for backports to the gcc-6 and gcc-5 branches

> after some soak time?


Yes, please.  Thanks.
Rainer Orth Nov. 11, 2016, 10:03 a.m. UTC | #2
Hi Bruce,

> On 11/03/16 07:11, Rainer Orth wrote:

>>

>> Ok for mainline now, and for backports to the gcc-6 and gcc-5 branches

>> after some soak time?

>

> Yes, please.  Thanks.


unfortunately, I didn't look closly enough when checking for failures.
There is one which I thought was preexisting:

math.h /vol/gcc/src/hg/trunk/local/fixincludes/tests/base/math.h differ: char 1135, line 57
*** math.h	Thu Nov 10 22:32:14 2016
--- /vol/gcc/src/hg/trunk/local/fixincludes/tests/base/math.h	Thu Nov 10 18:49:36 2016
***************
*** 54,61 ****
--- 54,63 ----
  
  #if defined( HPUX11_FABSF_CHECK )
  #ifdef _PA_RISC
+ #ifndef __cplusplus
  #  define fabsf(x) ((float)fabs((double)(float)(x)))
  #endif
+ #endif
  #endif  /* HPUX11_FABSF_CHECK */
  
Closer inspection shows that this is due to hpux11_fabsf using

    bypass    = "__cplusplus";

While this is fine for the fix itself, it's quite fragile since (as this
patch shows) it breaks as soon as any math.h test_text happens to
include __cplusplus, which is not that unlikely ;-)

I guess the solution is to use a more specific bypass pattern to make
the fix more robust.

	Rainer

-- 
-----------------------------------------------------------------------------
Rainer Orth, Center for Biotechnology, Bielefeld University
Jonathan Wakely Nov. 17, 2016, 4:53 p.m. UTC | #3
On 03/11/16 15:11 +0100, Rainer Orth wrote:
>Fortunately, this is all easily fixed by wrapping the affected templates

>in a new macro.  That's what this patch does.  The new libstdc++

>acinclude.m4 test may well need wording changes in comments etc. and can

>perhaps be shortened a bit, bit it worked for me.


See below.

>The fixincludes part passes make check.

>

>The patch has been regtested (C++ only) on

>

>* Solaris 11.2 SRU 13.6 (i.e. without both overloads and templates in

>  <iso/math_c99.h>),

>

>* Solaris 11.3 SRU 3.6 (i.e. with overloads only), and

>

>* Solaris 12 Build 110 (i.e. with both overloads and templates, and the

>  _GLIBCXX_USE_C99_MATH #undef's)

>

>* Linux/x86_64

>

>I've checked that __CORRECT_ISO_CPP11_MATH_H_PROTO[12] were defined in

>config.h as expected, and there were no testsuite regressions.  On the

>contrary, a couple of tests that before showed up as UNSUPPORTED due to

>the _GLIBCXX_USE_C99_MATH* #undef's now PASS as they should.

>

>Ok for mainline now, and for backports to the gcc-6 and gcc-5 branches

>after some soak time?


The change is OK in principle, but I'd prefer more meaningful names
for the macros ...

>--- a/libstdc++-v3/acinclude.m4

>+++ b/libstdc++-v3/acinclude.m4

>@@ -2181,7 +2181,8 @@ AC_DEFUN([GLIBCXX_CHECK_STDIO_PROTO], [

> ])

> 

> dnl

>-dnl Check whether required C++11 overloads are present in <math.h>.

>+dnl Check whether required C++11 overloads and templates are present

>+dnl in <math.h>.


The standard doesn't actually require templates to be used here, it
only requires "sufficient additional overloads" so that integral
arguments work. We happen to do that with templates, and apparently so
do the Solaris headers, but other implementations are possible. So a
more accurate description would be:

dnl Check whether required C++11 overloads for FP and integral types
dnl are present in <math.h>.

And rather than PROTO1 and PROTO2 the macros could be called PROTO_FP
for the overloads for FP types, and PROTO_INT (or just PROTO_I) for
the overloads for integral types (which happen to be templates in our
header).

>+      # Solaris 12 Build 90, Solaris 11.3 SRU 5.6, and Solaris 10 Patch

>+      # 11996[67]-02 introduced the C++11 <math.h> templates.

>+      AC_MSG_CHECKING([for C++11 <math.h> templates])

>+      AC_CACHE_VAL(glibcxx_cv_math11_template, [

>+	AC_COMPILE_IFELSE([AC_LANG_SOURCE(

>+	  [#include <math.h>

>+	   namespace std {

>+	     struct __true_type { };

>+	     struct __false_type { };


We don't need these structs.

>+	     template<typename _Tp>

>+	       struct __is_integer

>+	       {

>+	         enum { __value = 0 };

>+	         typedef __false_type __type;

>+	       };


We don't need a definition for the primary template, this will work:

	     template<typename _Tp>
	       struct __is_integer;

>+	     template<>

>+	       struct __is_integer<int>

>+	       {

>+	         enum { __value = 1 };

>+	         typedef __true_type __type;


The __type typedef is not needed here, just __value.

>+	       };

>+	   }

>+	   namespace __gnu_cxx {

>+	     template<bool, typename>

>+	       struct __enable_if 

>+	       { };


Again, no need to define the primary template:

	     template<bool, typename>
	       struct __enable_if;

>+	     template<typename _Tp>

>+	       struct __enable_if<true, _Tp>

>+	       { typedef _Tp __type; };

>+	   }


The suggestions above would make it shorter, while still remaining
accurate to what the real code in the header does. It could be reduced
even further without altering the meaning for the purposes of this
test:

>+	   namespace std {

>+	     template<typename _Tp>

>+	       constexpr typename __gnu_cxx::__enable_if

>+	       		 <__is_integer<_Tp>::__value, double>::__type

>+	       log2(_Tp __x)

>+	       { return __builtin_log2(__x); }


	     template<typename _Tp>
	       struct __enable_if_int;

	     template<>
	       struct __enable_if_int<int>
	       { typedef double __type; };

	     template<typename _Tp>
	       constexpr typename __enable_if_int<_Tp>::__type
	       log2(_Tp __x)
	       { return __builtin_log2(__x); }

I don't mind whether you go with this or just remove the unnecessary
structs, typedef and primary template bodies. Either is OK.

>+	   }

>+	   int

>+	   main (void)

>+	   {

>+	     int i = 1000;

>+	     return std::log2(i);

>+	   }
diff mbox

Patch

# HG changeset patch
# Parent  8df761378654bc962daa86f44aa2e4cf40804a7d
Don't define libstdc++-internal macros in Solaris 11/12 <math.h>

diff --git a/fixincludes/inclhack.def b/fixincludes/inclhack.def
--- a/fixincludes/inclhack.def
+++ b/fixincludes/inclhack.def
@@ -3787,6 +3787,23 @@  fix = {
 };
 
 /*
+ * Some versions of Solaris 10+ <math.h> #undef libstdc++-internal macros.
+ */
+fix = {
+    hackname  = solaris_math_12;
+    files     = math.h;
+    mach      = '*-*-solaris2*';
+    select    = '#undef.*_GLIBCXX_USE_C99_MATH';
+    sed       = "/#undef[ \t]*_GLIBCXX_USE_C99_MATH/d";
+    test_text = << _EOText_
+#if __cplusplus >= 201103L
+#undef  _GLIBCXX_USE_C99_MATH
+#undef  _GLIBCXX_USE_C99_MATH_TR1
+#endif
+_EOText_;
+};
+
+/*
  * Sun Solaris defines PTHREAD_ONCE_INIT as an array containing a
  * structure.  As such, it need two levels of brackets, but only
  * contains one.  Wrap the macro definition in an extra layer.
diff --git a/fixincludes/tests/base/math.h b/fixincludes/tests/base/math.h
--- a/fixincludes/tests/base/math.h
+++ b/fixincludes/tests/base/math.h
@@ -85,6 +85,12 @@  extern int class();
 #endif  /* RS6000_DOUBLE_CHECK */
 
 
+#if defined( SOLARIS_MATH_12_CHECK )
+#if __cplusplus >= 201103L
+#endif
+#endif  /* SOLARIS_MATH_12_CHECK */
+
+
 #if defined( STRICT_ANSI_NOT_CTD_CHECK )
 #if 1 && \
 && defined(mumbling) |& ( !defined(__STRICT_ANSI__)) \
diff --git a/libstdc++-v3/acinclude.m4 b/libstdc++-v3/acinclude.m4
--- a/libstdc++-v3/acinclude.m4
+++ b/libstdc++-v3/acinclude.m4
@@ -2181,7 +2181,8 @@  AC_DEFUN([GLIBCXX_CHECK_STDIO_PROTO], [
 ])
 
 dnl
-dnl Check whether required C++11 overloads are present in <math.h>.
+dnl Check whether required C++11 overloads and templates are present
+dnl in <math.h>.
 dnl
 AC_DEFUN([GLIBCXX_CHECK_MATH11_PROTO], [
 
@@ -2192,8 +2193,8 @@  AC_DEFUN([GLIBCXX_CHECK_MATH11_PROTO], [
 
   case "$host" in
     *-*-solaris2.*)
-      # Solaris 12 introduced the C++11 <math.h> overloads.  A backport to
-      # a Solaris 11.3 SRU is likely, maybe even a Solaris 10 patch.
+      # Solaris 12 Build 86, Solaris 11.3 SRU 3.6, and Solaris 10 Patch
+      # 11996[67]-02 introduced the C++11 <math.h> overloads.
       AC_MSG_CHECKING([for C++11 <math.h> overloads])
       AC_CACHE_VAL(glibcxx_cv_math11_overload, [
 	AC_COMPILE_IFELSE([AC_LANG_SOURCE(
@@ -2209,16 +2210,76 @@  AC_DEFUN([GLIBCXX_CHECK_MATH11_PROTO], [
       )])
 
       # autoheader cannot handle indented templates.
-      AH_VERBATIM([__CORRECT_ISO_CPP11_MATH_H_PROTO],
+      AH_VERBATIM([__CORRECT_ISO_CPP11_MATH_H_PROTO1],
         [/* Define if all C++11 overloads are available in <math.h>.  */
 #if __cplusplus >= 201103L
-#undef __CORRECT_ISO_CPP11_MATH_H_PROTO
+#undef __CORRECT_ISO_CPP11_MATH_H_PROTO1
 #endif])
 
       if test $glibcxx_cv_math11_overload = yes; then
-        AC_DEFINE(__CORRECT_ISO_CPP11_MATH_H_PROTO)
+        AC_DEFINE(__CORRECT_ISO_CPP11_MATH_H_PROTO1)
       fi
       AC_MSG_RESULT([$glibcxx_cv_math11_overload])
+
+      # Solaris 12 Build 90, Solaris 11.3 SRU 5.6, and Solaris 10 Patch
+      # 11996[67]-02 introduced the C++11 <math.h> templates.
+      AC_MSG_CHECKING([for C++11 <math.h> templates])
+      AC_CACHE_VAL(glibcxx_cv_math11_template, [
+	AC_COMPILE_IFELSE([AC_LANG_SOURCE(
+	  [#include <math.h>
+	   namespace std {
+	     struct __true_type { };
+	     struct __false_type { };
+	     template<typename _Tp>
+	       struct __is_integer
+	       {
+	         enum { __value = 0 };
+	         typedef __false_type __type;
+	       };
+	     template<>
+	       struct __is_integer<int>
+	       {
+	         enum { __value = 1 };
+	         typedef __true_type __type;
+	       };
+	   }
+	   namespace __gnu_cxx {
+	     template<bool, typename>
+	       struct __enable_if 
+	       { };
+	     template<typename _Tp>
+	       struct __enable_if<true, _Tp>
+	       { typedef _Tp __type; };
+	   }
+	   namespace std {
+	     template<typename _Tp>
+	       constexpr typename __gnu_cxx::__enable_if
+	       		 <__is_integer<_Tp>::__value, double>::__type
+	       log2(_Tp __x)
+	       { return __builtin_log2(__x); }
+	   }
+	   int
+	   main (void)
+	   {
+	     int i = 1000;
+	     return std::log2(i);
+	   }
+	])],
+	[glibcxx_cv_math11_template=no],
+	[glibcxx_cv_math11_template=yes]
+      )])
+
+      # autoheader cannot handle indented templates.
+      AH_VERBATIM([__CORRECT_ISO_CPP11_MATH_H_PROTO2],
+        [/* Define if all C++11 templates are available in <math.h>.  */
+#if __cplusplus >= 201103L
+#undef __CORRECT_ISO_CPP11_MATH_H_PROTO2
+#endif])
+
+      if test $glibcxx_cv_math11_template = yes; then
+        AC_DEFINE(__CORRECT_ISO_CPP11_MATH_H_PROTO2)
+      fi
+      AC_MSG_RESULT([$glibcxx_cv_math11_template])
       ;;
     *)
       # If <math.h> defines the obsolete isinf(double) and isnan(double)
diff --git a/libstdc++-v3/include/c_global/cmath b/libstdc++-v3/include/c_global/cmath
--- a/libstdc++-v3/include/c_global/cmath
+++ b/libstdc++-v3/include/c_global/cmath
@@ -539,7 +539,7 @@  namespace std _GLIBCXX_VISIBILITY(defaul
 
 #if __cplusplus >= 201103L
 
-#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO
+#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO1
   constexpr int
   fpclassify(float __x)
   { return __builtin_fpclassify(FP_NAN, FP_INFINITE, FP_NORMAL,
@@ -556,13 +556,15 @@  namespace std _GLIBCXX_VISIBILITY(defaul
 				FP_SUBNORMAL, FP_ZERO, __x); }
 #endif
 
+#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO2
   template<typename _Tp>
     constexpr typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value,
                                               int>::__type
     fpclassify(_Tp __x)
     { return __x != 0 ? FP_NORMAL : FP_ZERO; }
+#endif
 
-#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO
+#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO1
   constexpr bool
   isfinite(float __x)
   { return __builtin_isfinite(__x); }
@@ -576,13 +578,15 @@  namespace std _GLIBCXX_VISIBILITY(defaul
   { return __builtin_isfinite(__x); }
 #endif
 
+#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO2
   template<typename _Tp>
     constexpr typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value,
                                               bool>::__type
     isfinite(_Tp __x)
     { return true; }
+#endif
 
-#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO
+#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO1
   constexpr bool
   isinf(float __x)
   { return __builtin_isinf(__x); }
@@ -601,13 +605,15 @@  namespace std _GLIBCXX_VISIBILITY(defaul
   { return __builtin_isinf(__x); }
 #endif
 
+#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO2
   template<typename _Tp>
     constexpr typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value,
                                               bool>::__type
     isinf(_Tp __x)
     { return false; }
+#endif
 
-#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO
+#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO1
   constexpr bool
   isnan(float __x)
   { return __builtin_isnan(__x); }
@@ -626,13 +632,15 @@  namespace std _GLIBCXX_VISIBILITY(defaul
   { return __builtin_isnan(__x); }
 #endif
 
+#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO2
   template<typename _Tp>
     constexpr typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value,
                                               bool>::__type
     isnan(_Tp __x)
     { return false; }
+#endif
 
-#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO
+#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO1
   constexpr bool
   isnormal(float __x)
   { return __builtin_isnormal(__x); }
@@ -646,13 +654,15 @@  namespace std _GLIBCXX_VISIBILITY(defaul
   { return __builtin_isnormal(__x); }
 #endif
 
+#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO2
   template<typename _Tp>
     constexpr typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value,
                                               bool>::__type
     isnormal(_Tp __x)
     { return __x != 0 ? true : false; }
+#endif
 
-#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO
+#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO1
   // Note: middle-end/36757 is fixed, __builtin_signbit is type-generic.
   constexpr bool
   signbit(float __x)
@@ -667,13 +677,15 @@  namespace std _GLIBCXX_VISIBILITY(defaul
   { return __builtin_signbit(__x); }
 #endif
 
+#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO2
   template<typename _Tp>
     constexpr typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value,
                                               bool>::__type
     signbit(_Tp __x)
     { return __x < 0 ? true : false; }
+#endif
 
-#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO
+#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO1
   constexpr bool
   isgreater(float __x, float __y)
   { return __builtin_isgreater(__x, __y); }
@@ -687,6 +699,7 @@  namespace std _GLIBCXX_VISIBILITY(defaul
   { return __builtin_isgreater(__x, __y); }
 #endif
 
+#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO2
   template<typename _Tp, typename _Up>
     constexpr typename
     __gnu_cxx::__enable_if<(__is_arithmetic<_Tp>::__value
@@ -696,8 +709,9 @@  namespace std _GLIBCXX_VISIBILITY(defaul
       typedef typename __gnu_cxx::__promote_2<_Tp, _Up>::__type __type;
       return __builtin_isgreater(__type(__x), __type(__y));
     }
+#endif
 
-#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO
+#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO1
   constexpr bool
   isgreaterequal(float __x, float __y)
   { return __builtin_isgreaterequal(__x, __y); }
@@ -711,6 +725,7 @@  namespace std _GLIBCXX_VISIBILITY(defaul
   { return __builtin_isgreaterequal(__x, __y); }
 #endif
 
+#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO2
   template<typename _Tp, typename _Up>
     constexpr typename
     __gnu_cxx::__enable_if<(__is_arithmetic<_Tp>::__value
@@ -720,8 +735,9 @@  namespace std _GLIBCXX_VISIBILITY(defaul
       typedef typename __gnu_cxx::__promote_2<_Tp, _Up>::__type __type;
       return __builtin_isgreaterequal(__type(__x), __type(__y));
     }
+#endif
 
-#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO
+#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO1
   constexpr bool
   isless(float __x, float __y)
   { return __builtin_isless(__x, __y); }
@@ -735,6 +751,7 @@  namespace std _GLIBCXX_VISIBILITY(defaul
   { return __builtin_isless(__x, __y); }
 #endif
 
+#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO2
   template<typename _Tp, typename _Up>
     constexpr typename
     __gnu_cxx::__enable_if<(__is_arithmetic<_Tp>::__value
@@ -744,8 +761,9 @@  namespace std _GLIBCXX_VISIBILITY(defaul
       typedef typename __gnu_cxx::__promote_2<_Tp, _Up>::__type __type;
       return __builtin_isless(__type(__x), __type(__y));
     }
+#endif
 
-#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO
+#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO1
   constexpr bool
   islessequal(float __x, float __y)
   { return __builtin_islessequal(__x, __y); }
@@ -759,6 +777,7 @@  namespace std _GLIBCXX_VISIBILITY(defaul
   { return __builtin_islessequal(__x, __y); }
 #endif
 
+#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO2
   template<typename _Tp, typename _Up>
     constexpr typename
     __gnu_cxx::__enable_if<(__is_arithmetic<_Tp>::__value
@@ -768,8 +787,9 @@  namespace std _GLIBCXX_VISIBILITY(defaul
       typedef typename __gnu_cxx::__promote_2<_Tp, _Up>::__type __type;
       return __builtin_islessequal(__type(__x), __type(__y));
     }
+#endif
 
-#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO
+#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO1
   constexpr bool
   islessgreater(float __x, float __y)
   { return __builtin_islessgreater(__x, __y); }
@@ -783,6 +803,7 @@  namespace std _GLIBCXX_VISIBILITY(defaul
   { return __builtin_islessgreater(__x, __y); }
 #endif
 
+#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO2
   template<typename _Tp, typename _Up>
     constexpr typename
     __gnu_cxx::__enable_if<(__is_arithmetic<_Tp>::__value
@@ -792,8 +813,9 @@  namespace std _GLIBCXX_VISIBILITY(defaul
       typedef typename __gnu_cxx::__promote_2<_Tp, _Up>::__type __type;
       return __builtin_islessgreater(__type(__x), __type(__y));
     }
+#endif
 
-#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO
+#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO1
   constexpr bool
   isunordered(float __x, float __y)
   { return __builtin_isunordered(__x, __y); }
@@ -807,6 +829,7 @@  namespace std _GLIBCXX_VISIBILITY(defaul
   { return __builtin_isunordered(__x, __y); }
 #endif
 
+#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO2
   template<typename _Tp, typename _Up>
     constexpr typename
     __gnu_cxx::__enable_if<(__is_arithmetic<_Tp>::__value
@@ -816,6 +839,7 @@  namespace std _GLIBCXX_VISIBILITY(defaul
       typedef typename __gnu_cxx::__promote_2<_Tp, _Up>::__type __type;
       return __builtin_isunordered(__type(__x), __type(__y));
     }
+#endif
 
 #else
 
@@ -1196,7 +1220,7 @@  namespace std _GLIBCXX_VISIBILITY(defaul
   using ::truncl;
 
   /// Additional overloads.
-#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO
+#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO1
   constexpr float
   acosh(float __x)
   { return __builtin_acoshf(__x); }
@@ -1206,13 +1230,15 @@  namespace std _GLIBCXX_VISIBILITY(defaul
   { return __builtin_acoshl(__x); }
 #endif
 
+#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO2
   template<typename _Tp>
     constexpr typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, 
                                               double>::__type
     acosh(_Tp __x)
     { return __builtin_acosh(__x); }
+#endif
 
-#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO
+#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO1
   constexpr float
   asinh(float __x)
   { return __builtin_asinhf(__x); }
@@ -1222,13 +1248,15 @@  namespace std _GLIBCXX_VISIBILITY(defaul
   { return __builtin_asinhl(__x); }
 #endif
 
+#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO2
   template<typename _Tp>
     constexpr typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, 
                                               double>::__type
     asinh(_Tp __x)
     { return __builtin_asinh(__x); }
+#endif
 
-#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO
+#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO1
   constexpr float
   atanh(float __x)
   { return __builtin_atanhf(__x); }
@@ -1238,13 +1266,15 @@  namespace std _GLIBCXX_VISIBILITY(defaul
   { return __builtin_atanhl(__x); }
 #endif
 
+#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO2
   template<typename _Tp>
     constexpr typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, 
                                               double>::__type
     atanh(_Tp __x)
     { return __builtin_atanh(__x); }
+#endif
 
-#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO
+#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO1
   constexpr float
   cbrt(float __x)
   { return __builtin_cbrtf(__x); }
@@ -1254,13 +1284,15 @@  namespace std _GLIBCXX_VISIBILITY(defaul
   { return __builtin_cbrtl(__x); }
 #endif
 
+#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO2
   template<typename _Tp>
     constexpr typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, 
                                               double>::__type
     cbrt(_Tp __x)
     { return __builtin_cbrt(__x); }
+#endif
 
-#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO
+#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO1
   constexpr float
   copysign(float __x, float __y)
   { return __builtin_copysignf(__x, __y); }
@@ -1270,6 +1302,7 @@  namespace std _GLIBCXX_VISIBILITY(defaul
   { return __builtin_copysignl(__x, __y); }
 #endif
 
+#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO2
   template<typename _Tp, typename _Up>
     constexpr typename __gnu_cxx::__promote_2<_Tp, _Up>::__type
     copysign(_Tp __x, _Up __y)
@@ -1277,8 +1310,9 @@  namespace std _GLIBCXX_VISIBILITY(defaul
       typedef typename __gnu_cxx::__promote_2<_Tp, _Up>::__type __type;
       return copysign(__type(__x), __type(__y));
     }
+#endif
 
-#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO
+#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO1
   constexpr float
   erf(float __x)
   { return __builtin_erff(__x); }
@@ -1288,13 +1322,15 @@  namespace std _GLIBCXX_VISIBILITY(defaul
   { return __builtin_erfl(__x); }
 #endif
 
+#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO2
   template<typename _Tp>
     constexpr typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, 
                                               double>::__type
     erf(_Tp __x)
     { return __builtin_erf(__x); }
+#endif
 
-#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO
+#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO1
   constexpr float
   erfc(float __x)
   { return __builtin_erfcf(__x); }
@@ -1304,13 +1340,15 @@  namespace std _GLIBCXX_VISIBILITY(defaul
   { return __builtin_erfcl(__x); }
 #endif
 
+#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO2
   template<typename _Tp>
     constexpr typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, 
                                               double>::__type
     erfc(_Tp __x)
     { return __builtin_erfc(__x); }
+#endif
 
-#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO
+#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO1
   constexpr float
   exp2(float __x)
   { return __builtin_exp2f(__x); }
@@ -1320,13 +1358,15 @@  namespace std _GLIBCXX_VISIBILITY(defaul
   { return __builtin_exp2l(__x); }
 #endif
 
+#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO2
   template<typename _Tp>
     constexpr typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, 
                                               double>::__type
     exp2(_Tp __x)
     { return __builtin_exp2(__x); }
+#endif
 
-#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO
+#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO1
   constexpr float
   expm1(float __x)
   { return __builtin_expm1f(__x); }
@@ -1336,13 +1376,15 @@  namespace std _GLIBCXX_VISIBILITY(defaul
   { return __builtin_expm1l(__x); }
 #endif
 
+#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO2
   template<typename _Tp>
     constexpr typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, 
                                               double>::__type
     expm1(_Tp __x)
     { return __builtin_expm1(__x); }
+#endif
 
-#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO
+#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO1
   constexpr float
   fdim(float __x, float __y)
   { return __builtin_fdimf(__x, __y); }
@@ -1352,6 +1394,7 @@  namespace std _GLIBCXX_VISIBILITY(defaul
   { return __builtin_fdiml(__x, __y); }
 #endif
 
+#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO2
   template<typename _Tp, typename _Up>
     constexpr typename __gnu_cxx::__promote_2<_Tp, _Up>::__type
     fdim(_Tp __x, _Up __y)
@@ -1359,8 +1402,9 @@  namespace std _GLIBCXX_VISIBILITY(defaul
       typedef typename __gnu_cxx::__promote_2<_Tp, _Up>::__type __type;
       return fdim(__type(__x), __type(__y));
     }
+#endif
 
-#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO
+#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO1
   constexpr float
   fma(float __x, float __y, float __z)
   { return __builtin_fmaf(__x, __y, __z); }
@@ -1370,6 +1414,7 @@  namespace std _GLIBCXX_VISIBILITY(defaul
   { return __builtin_fmal(__x, __y, __z); }
 #endif
 
+#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO2
   template<typename _Tp, typename _Up, typename _Vp>
     constexpr typename __gnu_cxx::__promote_3<_Tp, _Up, _Vp>::__type
     fma(_Tp __x, _Up __y, _Vp __z)
@@ -1377,8 +1422,9 @@  namespace std _GLIBCXX_VISIBILITY(defaul
       typedef typename __gnu_cxx::__promote_3<_Tp, _Up, _Vp>::__type __type;
       return fma(__type(__x), __type(__y), __type(__z));
     }
+#endif
 
-#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO
+#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO1
   constexpr float
   fmax(float __x, float __y)
   { return __builtin_fmaxf(__x, __y); }
@@ -1388,6 +1434,7 @@  namespace std _GLIBCXX_VISIBILITY(defaul
   { return __builtin_fmaxl(__x, __y); }
 #endif
 
+#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO2
   template<typename _Tp, typename _Up>
     constexpr typename __gnu_cxx::__promote_2<_Tp, _Up>::__type
     fmax(_Tp __x, _Up __y)
@@ -1395,8 +1442,9 @@  namespace std _GLIBCXX_VISIBILITY(defaul
       typedef typename __gnu_cxx::__promote_2<_Tp, _Up>::__type __type;
       return fmax(__type(__x), __type(__y));
     }
+#endif
 
-#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO
+#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO1
   constexpr float
   fmin(float __x, float __y)
   { return __builtin_fminf(__x, __y); }
@@ -1406,6 +1454,7 @@  namespace std _GLIBCXX_VISIBILITY(defaul
   { return __builtin_fminl(__x, __y); }
 #endif
 
+#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO2
   template<typename _Tp, typename _Up>
     constexpr typename __gnu_cxx::__promote_2<_Tp, _Up>::__type
     fmin(_Tp __x, _Up __y)
@@ -1413,8 +1462,9 @@  namespace std _GLIBCXX_VISIBILITY(defaul
       typedef typename __gnu_cxx::__promote_2<_Tp, _Up>::__type __type;
       return fmin(__type(__x), __type(__y));
     }
+#endif
 
-#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO
+#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO1
   constexpr float
   hypot(float __x, float __y)
   { return __builtin_hypotf(__x, __y); }
@@ -1424,6 +1474,7 @@  namespace std _GLIBCXX_VISIBILITY(defaul
   { return __builtin_hypotl(__x, __y); }
 #endif
 
+#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO2
   template<typename _Tp, typename _Up>
     constexpr typename __gnu_cxx::__promote_2<_Tp, _Up>::__type
     hypot(_Tp __x, _Up __y)
@@ -1431,8 +1482,9 @@  namespace std _GLIBCXX_VISIBILITY(defaul
       typedef typename __gnu_cxx::__promote_2<_Tp, _Up>::__type __type;
       return hypot(__type(__x), __type(__y));
     }
+#endif
 
-#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO
+#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO1
   constexpr int
   ilogb(float __x)
   { return __builtin_ilogbf(__x); }
@@ -1442,14 +1494,16 @@  namespace std _GLIBCXX_VISIBILITY(defaul
   { return __builtin_ilogbl(__x); }
 #endif
 
+#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO2
   template<typename _Tp>
     constexpr
     typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, 
                                     int>::__type
     ilogb(_Tp __x)
     { return __builtin_ilogb(__x); }
+#endif
 
-#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO
+#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO1
   constexpr float
   lgamma(float __x)
   { return __builtin_lgammaf(__x); }
@@ -1459,13 +1513,15 @@  namespace std _GLIBCXX_VISIBILITY(defaul
   { return __builtin_lgammal(__x); }
 #endif
 
+#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO2
   template<typename _Tp>
     constexpr typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, 
                                               double>::__type
     lgamma(_Tp __x)
     { return __builtin_lgamma(__x); }
+#endif
 
-#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO
+#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO1
   constexpr long long
   llrint(float __x)
   { return __builtin_llrintf(__x); }
@@ -1475,13 +1531,15 @@  namespace std _GLIBCXX_VISIBILITY(defaul
   { return __builtin_llrintl(__x); }
 #endif
 
+#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO2
   template<typename _Tp>
     constexpr typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, 
                                               long long>::__type
     llrint(_Tp __x)
     { return __builtin_llrint(__x); }
+#endif
 
-#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO
+#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO1
   constexpr long long
   llround(float __x)
   { return __builtin_llroundf(__x); }
@@ -1491,13 +1549,15 @@  namespace std _GLIBCXX_VISIBILITY(defaul
   { return __builtin_llroundl(__x); }
 #endif
 
+#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO2
   template<typename _Tp>
     constexpr typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, 
                                               long long>::__type
     llround(_Tp __x)
     { return __builtin_llround(__x); }
+#endif
 
-#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO
+#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO1
   constexpr float
   log1p(float __x)
   { return __builtin_log1pf(__x); }
@@ -1507,13 +1567,15 @@  namespace std _GLIBCXX_VISIBILITY(defaul
   { return __builtin_log1pl(__x); }
 #endif
 
+#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO2
   template<typename _Tp>
     constexpr typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, 
                                               double>::__type
     log1p(_Tp __x)
     { return __builtin_log1p(__x); }
+#endif
 
-#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO
+#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO1
   // DR 568.
   constexpr float
   log2(float __x)
@@ -1524,13 +1586,15 @@  namespace std _GLIBCXX_VISIBILITY(defaul
   { return __builtin_log2l(__x); }
 #endif
 
+#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO2
   template<typename _Tp>
     constexpr typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, 
                                               double>::__type
     log2(_Tp __x)
     { return __builtin_log2(__x); }
+#endif
 
-#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO
+#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO1
   constexpr float
   logb(float __x)
   { return __builtin_logbf(__x); }
@@ -1540,13 +1604,15 @@  namespace std _GLIBCXX_VISIBILITY(defaul
   { return __builtin_logbl(__x); }
 #endif
 
+#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO2
   template<typename _Tp>
     constexpr typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, 
                                               double>::__type
     logb(_Tp __x)
     { return __builtin_logb(__x); }
+#endif
 
-#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO
+#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO1
   constexpr long
   lrint(float __x)
   { return __builtin_lrintf(__x); }
@@ -1556,13 +1622,15 @@  namespace std _GLIBCXX_VISIBILITY(defaul
   { return __builtin_lrintl(__x); }
 #endif
 
+#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO2
   template<typename _Tp>
     constexpr typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, 
                                               long>::__type
     lrint(_Tp __x)
     { return __builtin_lrint(__x); }
+#endif
 
-#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO
+#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO1
   constexpr long
   lround(float __x)
   { return __builtin_lroundf(__x); }
@@ -1572,13 +1640,15 @@  namespace std _GLIBCXX_VISIBILITY(defaul
   { return __builtin_lroundl(__x); }
 #endif
 
+#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO2
   template<typename _Tp>
     constexpr typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, 
                                               long>::__type
     lround(_Tp __x)
     { return __builtin_lround(__x); }
+#endif
 
-#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO
+#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO1
   constexpr float
   nearbyint(float __x)
   { return __builtin_nearbyintf(__x); }
@@ -1588,13 +1658,15 @@  namespace std _GLIBCXX_VISIBILITY(defaul
   { return __builtin_nearbyintl(__x); }
 #endif
 
+#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO2
   template<typename _Tp>
     constexpr typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, 
                                               double>::__type
     nearbyint(_Tp __x)
     { return __builtin_nearbyint(__x); }
+#endif
 
-#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO
+#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO1
   constexpr float
   nextafter(float __x, float __y)
   { return __builtin_nextafterf(__x, __y); }
@@ -1604,6 +1676,7 @@  namespace std _GLIBCXX_VISIBILITY(defaul
   { return __builtin_nextafterl(__x, __y); }
 #endif
 
+#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO2
   template<typename _Tp, typename _Up>
     constexpr typename __gnu_cxx::__promote_2<_Tp, _Up>::__type
     nextafter(_Tp __x, _Up __y)
@@ -1611,8 +1684,9 @@  namespace std _GLIBCXX_VISIBILITY(defaul
       typedef typename __gnu_cxx::__promote_2<_Tp, _Up>::__type __type;
       return nextafter(__type(__x), __type(__y));
     }
+#endif
 
-#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO
+#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO1
   constexpr float
   nexttoward(float __x, long double __y)
   { return __builtin_nexttowardf(__x, __y); }
@@ -1622,13 +1696,15 @@  namespace std _GLIBCXX_VISIBILITY(defaul
   { return __builtin_nexttowardl(__x, __y); }
 #endif
 
+#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO2
   template<typename _Tp>
     constexpr typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, 
                                               double>::__type
     nexttoward(_Tp __x, long double __y)
     { return __builtin_nexttoward(__x, __y); }
+#endif
 
-#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO
+#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO1
   constexpr float
   remainder(float __x, float __y)
   { return __builtin_remainderf(__x, __y); }
@@ -1638,6 +1714,7 @@  namespace std _GLIBCXX_VISIBILITY(defaul
   { return __builtin_remainderl(__x, __y); }
 #endif
 
+#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO2
   template<typename _Tp, typename _Up>
     constexpr typename __gnu_cxx::__promote_2<_Tp, _Up>::__type
     remainder(_Tp __x, _Up __y)
@@ -1645,8 +1722,9 @@  namespace std _GLIBCXX_VISIBILITY(defaul
       typedef typename __gnu_cxx::__promote_2<_Tp, _Up>::__type __type;
       return remainder(__type(__x), __type(__y));
     }
+#endif
 
-#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO
+#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO1
   inline float
   remquo(float __x, float __y, int* __pquo)
   { return __builtin_remquof(__x, __y, __pquo); }
@@ -1656,6 +1734,7 @@  namespace std _GLIBCXX_VISIBILITY(defaul
   { return __builtin_remquol(__x, __y, __pquo); }
 #endif
 
+#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO2
   template<typename _Tp, typename _Up>
     inline typename __gnu_cxx::__promote_2<_Tp, _Up>::__type
     remquo(_Tp __x, _Up __y, int* __pquo)
@@ -1663,8 +1742,9 @@  namespace std _GLIBCXX_VISIBILITY(defaul
       typedef typename __gnu_cxx::__promote_2<_Tp, _Up>::__type __type;
       return remquo(__type(__x), __type(__y), __pquo);
     }
+#endif
 
-#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO
+#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO1
   constexpr float
   rint(float __x)
   { return __builtin_rintf(__x); }
@@ -1674,13 +1754,15 @@  namespace std _GLIBCXX_VISIBILITY(defaul
   { return __builtin_rintl(__x); }
 #endif
 
+#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO2
   template<typename _Tp>
     constexpr typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, 
                                               double>::__type
     rint(_Tp __x)
     { return __builtin_rint(__x); }
+#endif
 
-#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO
+#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO1
   constexpr float
   round(float __x)
   { return __builtin_roundf(__x); }
@@ -1690,13 +1772,15 @@  namespace std _GLIBCXX_VISIBILITY(defaul
   { return __builtin_roundl(__x); }
 #endif
 
+#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO2
   template<typename _Tp>
     constexpr typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, 
                                               double>::__type
     round(_Tp __x)
     { return __builtin_round(__x); }
+#endif
 
-#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO
+#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO1
   constexpr float
   scalbln(float __x, long __ex)
   { return __builtin_scalblnf(__x, __ex); }
@@ -1706,13 +1790,15 @@  namespace std _GLIBCXX_VISIBILITY(defaul
   { return __builtin_scalblnl(__x, __ex); }
 #endif
 
+#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO2
   template<typename _Tp>
     constexpr typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, 
                                               double>::__type
     scalbln(_Tp __x, long __ex)
     { return __builtin_scalbln(__x, __ex); }
+#endif
  
-#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO
+#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO1
   constexpr float
   scalbn(float __x, int __ex)
   { return __builtin_scalbnf(__x, __ex); }
@@ -1722,13 +1808,15 @@  namespace std _GLIBCXX_VISIBILITY(defaul
   { return __builtin_scalbnl(__x, __ex); }
 #endif
 
+#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO2
   template<typename _Tp>
     constexpr typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, 
                                               double>::__type
     scalbn(_Tp __x, int __ex)
     { return __builtin_scalbn(__x, __ex); }
+#endif
 
-#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO
+#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO1
   constexpr float
   tgamma(float __x)
   { return __builtin_tgammaf(__x); }
@@ -1738,13 +1826,15 @@  namespace std _GLIBCXX_VISIBILITY(defaul
   { return __builtin_tgammal(__x); }
 #endif
 
+#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO2
   template<typename _Tp>
     constexpr typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, 
                                               double>::__type
     tgamma(_Tp __x)
     { return __builtin_tgamma(__x); }
+#endif
  
-#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO
+#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO1
   constexpr float
   trunc(float __x)
   { return __builtin_truncf(__x); }
@@ -1754,11 +1844,13 @@  namespace std _GLIBCXX_VISIBILITY(defaul
   { return __builtin_truncl(__x); }
 #endif
 
+#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO2
   template<typename _Tp>
     constexpr typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, 
                                               double>::__type
     trunc(_Tp __x)
     { return __builtin_trunc(__x); }
+#endif
 
 _GLIBCXX_END_NAMESPACE_VERSION
 } // namespace
diff --git a/libstdc++-v3/include/tr1/cmath b/libstdc++-v3/include/tr1/cmath
--- a/libstdc++-v3/include/tr1/cmath
+++ b/libstdc++-v3/include/tr1/cmath
@@ -490,7 +490,7 @@  namespace tr1
 
   // In C++03 we need to provide the additional overloads.
 
-#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO
+#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO1
   inline float
   acosh(float __x)
   { return __builtin_acoshf(__x); }
@@ -506,7 +506,7 @@  namespace tr1
     acosh(_Tp __x)
     { return __builtin_acosh(__x); }
 
-#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO
+#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO1
   inline float
   asinh(float __x)
   { return __builtin_asinhf(__x); }
@@ -522,7 +522,7 @@  namespace tr1
     asinh(_Tp __x)
     { return __builtin_asinh(__x); }
 
-#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO
+#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO1
   inline float
   atanh(float __x)
   { return __builtin_atanhf(__x); }
@@ -538,7 +538,7 @@  namespace tr1
     atanh(_Tp __x)
     { return __builtin_atanh(__x); }
 
-#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO
+#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO1
   inline float
   cbrt(float __x)
   { return __builtin_cbrtf(__x); }
@@ -554,7 +554,7 @@  namespace tr1
     cbrt(_Tp __x)
     { return __builtin_cbrt(__x); }
 
-#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO
+#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO1
   inline float
   copysign(float __x, float __y)
   { return __builtin_copysignf(__x, __y); }
@@ -572,7 +572,7 @@  namespace tr1
       return copysign(__type(__x), __type(__y));
     }
 
-#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO
+#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO1
   inline float
   erf(float __x)
   { return __builtin_erff(__x); }
@@ -588,7 +588,7 @@  namespace tr1
     erf(_Tp __x)
     { return __builtin_erf(__x); }
 
-#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO
+#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO1
   inline float
   erfc(float __x)
   { return __builtin_erfcf(__x); }
@@ -604,7 +604,7 @@  namespace tr1
     erfc(_Tp __x)
     { return __builtin_erfc(__x); }
 
-#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO
+#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO1
   inline float
   exp2(float __x)
   { return __builtin_exp2f(__x); }
@@ -620,7 +620,7 @@  namespace tr1
     exp2(_Tp __x)
     { return __builtin_exp2(__x); }
 
-#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO
+#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO1
   inline float
   expm1(float __x)
   { return __builtin_expm1f(__x); }
@@ -636,7 +636,7 @@  namespace tr1
     expm1(_Tp __x)
     { return __builtin_expm1(__x); }
 
-#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO
+#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO1
   inline float
   fdim(float __x, float __y)
   { return __builtin_fdimf(__x, __y); }
@@ -654,7 +654,7 @@  namespace tr1
       return fdim(__type(__x), __type(__y));
     }
 
-#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO
+#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO1
   inline float
   fma(float __x, float __y, float __z)
   { return __builtin_fmaf(__x, __y, __z); }
@@ -672,7 +672,7 @@  namespace tr1
       return fma(__type(__x), __type(__y), __type(__z));
     }
 
-#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO
+#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO1
   inline float
   fmax(float __x, float __y)
   { return __builtin_fmaxf(__x, __y); }
@@ -690,7 +690,7 @@  namespace tr1
       return fmax(__type(__x), __type(__y));
     }
 
-#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO
+#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO1
   inline float
   fmin(float __x, float __y)
   { return __builtin_fminf(__x, __y); }
@@ -708,7 +708,7 @@  namespace tr1
       return fmin(__type(__x), __type(__y));
     }
 
-#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO
+#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO1
   inline float
   hypot(float __x, float __y)
   { return __builtin_hypotf(__x, __y); }
@@ -726,7 +726,7 @@  namespace tr1
       return hypot(__type(__y), __type(__x));
     }
 
-#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO
+#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO1
   inline int
   ilogb(float __x)
   { return __builtin_ilogbf(__x); }
@@ -742,7 +742,7 @@  namespace tr1
     ilogb(_Tp __x)
     { return __builtin_ilogb(__x); }
 
-#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO
+#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO1
   inline float
   lgamma(float __x)
   { return __builtin_lgammaf(__x); }
@@ -758,7 +758,7 @@  namespace tr1
     lgamma(_Tp __x)
     { return __builtin_lgamma(__x); }
 
-#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO
+#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO1
   inline long long
   llrint(float __x)
   { return __builtin_llrintf(__x); }
@@ -774,7 +774,7 @@  namespace tr1
     llrint(_Tp __x)
     { return __builtin_llrint(__x); }
 
-#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO
+#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO1
   inline long long
   llround(float __x)
   { return __builtin_llroundf(__x); }
@@ -790,7 +790,7 @@  namespace tr1
     llround(_Tp __x)
     { return __builtin_llround(__x); }
 
-#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO
+#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO1
   inline float
   log1p(float __x)
   { return __builtin_log1pf(__x); }
@@ -807,7 +807,7 @@  namespace tr1
     { return __builtin_log1p(__x); }
 
   // DR 568.
-#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO
+#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO1
   inline float
   log2(float __x)
   { return __builtin_log2f(__x); }
@@ -823,7 +823,7 @@  namespace tr1
     log2(_Tp __x)
     { return __builtin_log2(__x); }
 
-#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO
+#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO1
   inline float
   logb(float __x)
   { return __builtin_logbf(__x); }
@@ -841,7 +841,7 @@  namespace tr1
       return __builtin_logb(__x);
     }
 
-#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO
+#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO1
   inline long
   lrint(float __x)
   { return __builtin_lrintf(__x); }
@@ -857,7 +857,7 @@  namespace tr1
     lrint(_Tp __x)
     { return __builtin_lrint(__x); }
 
-#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO
+#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO1
   inline long
   lround(float __x)
   { return __builtin_lroundf(__x); }
@@ -873,7 +873,7 @@  namespace tr1
     lround(_Tp __x)
     { return __builtin_lround(__x); }
 
-#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO
+#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO1
   inline float
   nearbyint(float __x)
   { return __builtin_nearbyintf(__x); }
@@ -889,7 +889,7 @@  namespace tr1
     nearbyint(_Tp __x)
     { return __builtin_nearbyint(__x); }
 
-#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO
+#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO1
   inline float
   nextafter(float __x, float __y)
   { return __builtin_nextafterf(__x, __y); }
@@ -907,7 +907,7 @@  namespace tr1
       return nextafter(__type(__x), __type(__y));
     }
 
-#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO
+#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO1
   inline float
   nexttoward(float __x, long double __y)
   { return __builtin_nexttowardf(__x, __y); }
@@ -923,7 +923,7 @@  namespace tr1
     nexttoward(_Tp __x, long double __y)
     { return __builtin_nexttoward(__x, __y); }
 
-#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO
+#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO1
   inline float
   remainder(float __x, float __y)
   { return __builtin_remainderf(__x, __y); }
@@ -941,7 +941,7 @@  namespace tr1
       return remainder(__type(__x), __type(__y));
     }
 
-#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO
+#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO1
   inline float
   remquo(float __x, float __y, int* __pquo)
   { return __builtin_remquof(__x, __y, __pquo); }
@@ -959,7 +959,7 @@  namespace tr1
       return remquo(__type(__x), __type(__y), __pquo);
     }
 
-#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO
+#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO1
   inline float
   rint(float __x)
   { return __builtin_rintf(__x); }
@@ -975,7 +975,7 @@  namespace tr1
     rint(_Tp __x)
     { return __builtin_rint(__x); }
 
-#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO
+#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO1
   inline float
   round(float __x)
   { return __builtin_roundf(__x); }
@@ -991,7 +991,7 @@  namespace tr1
     round(_Tp __x)
     { return __builtin_round(__x); }
 
-#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO
+#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO1
   inline float
   scalbln(float __x, long __ex)
   { return __builtin_scalblnf(__x, __ex); }
@@ -1007,7 +1007,7 @@  namespace tr1
     scalbln(_Tp __x, long __ex)
     { return __builtin_scalbln(__x, __ex); }
  
-#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO
+#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO1
   inline float
   scalbn(float __x, int __ex)
   { return __builtin_scalbnf(__x, __ex); }
@@ -1023,7 +1023,7 @@  namespace tr1
     scalbn(_Tp __x, int __ex)
     { return __builtin_scalbn(__x, __ex); }
 
-#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO
+#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO1
   inline float
   tgamma(float __x)
   { return __builtin_tgammaf(__x); }
@@ -1039,7 +1039,7 @@  namespace tr1
     tgamma(_Tp __x)
     { return __builtin_tgamma(__x); }
  
-#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO
+#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO1
   inline float
   trunc(float __x)
   { return __builtin_truncf(__x); }
@@ -1084,7 +1084,7 @@  namespace tr1
   // the discussion about this issue here:
   // http://gcc.gnu.org/ml/gcc-patches/2012-09/msg01278.html
 
-#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO
+#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO1
   inline float
   pow(float __x, float __y)
   { return std::pow(__x, __y); }
@@ -1112,7 +1112,7 @@  namespace tr1
   // to std::fabs.
 
 #ifndef __CORRECT_ISO_CPP_MATH_H_PROTO
-#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO
+#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO1
   inline float
   fabs(float __x)
   { return __builtin_fabsf(__x); }