On 08/01/16 19:18 +0000, Jonathan Wakely wrote:
This resolves the longstanding issue that #include <math.h> uses the C
library header, which on most targets doesn't declare the additional
overloads required by C++11 26.8 [c.math], and similarly for
<stdlib.h>.
With this patch libstdc++ provides its own <math.h> and <stdlib.h>
wrappers, which are equivalent to <cmath> or <cstdlib> followed by
using-directives for all standard names. This means there are no more
inconsistencies in the contents of the <cxxx> and <xxx.h> headers.
Tested x86_64-linux, powerpc64le-linux, powerpc-aix,
x86_64-freebsd10.2, x86_64-dragonfly4.2
Committed to trunk.
commit 55b627c6c6b84fa05d01005bc7bff0860a280cc0
Author: Jonathan Wakely <jwak...@redhat.com>
Date: Mon Jan 18 18:28:58 2016 +0000
Add C++-conforming wrappers for stdlib.h and math.h
PR libstdc++/14608
PR libstdc++/60401
* include/Makefile.am: Use c_compatibility math.h and stdlib.h for
--enable-cheaders=c_global configs.
* include/Makefile.in: Regenerate.
* include/c_compatibility/math.h: Remove obsolete _GLIBCXX_NAMESPACE_C
test and allow inclusion from C files.
* include/c_compatibility/stdlib.h: Likewise. Support freestanding.
(at_quick_exit, quick_exit): Add using directives.
* include/c_global/cmath: Use #include_next for math.h.
* include/c_global/cstdlib: Use #include_next for stdlib.h.
* testsuite/26_numerics/headers/cmath/14608.cc: New.
* testsuite/26_numerics/headers/cmath/c99_classification_macros_c.cc:
Remove xfail for most targets.
* testsuite/26_numerics/headers/cstdlib/60401.cc: New.
diff --git a/libstdc++-v3/include/Makefile.am b/libstdc++-v3/include/Makefile.am
index 39327d9..573f057 100644
--- a/libstdc++-v3/include/Makefile.am
+++ b/libstdc++-v3/include/Makefile.am
@@ -740,7 +740,9 @@ if GLIBCXX_C_HEADERS_C_GLOBAL
c_compatibility_headers = \
${c_compatibility_srcdir}/complex.h \
${c_compatibility_srcdir}/fenv.h \
- ${c_compatibility_srcdir}/tgmath.h
+ ${c_compatibility_srcdir}/tgmath.h \
+ ${c_compatibility_srcdir}/math.h \
+ ${c_compatibility_srcdir}/stdlib.h
endif
if GLIBCXX_C_HEADERS_C
diff --git a/libstdc++-v3/include/Makefile.in b/libstdc++-v3/include/Makefile.in
index e74fae8..57f1ec5 100644
--- a/libstdc++-v3/include/Makefile.in
+++ b/libstdc++-v3/include/Makefile.in
@@ -1023,7 +1023,9 @@ c_compatibility_builddir = .
@GLIBCXX_C_HEADERS_C_GLOBAL_TRUE@c_compatibility_headers = \
@GLIBCXX_C_HEADERS_C_GLOBAL_TRUE@ ${c_compatibility_srcdir}/complex.h \
@GLIBCXX_C_HEADERS_C_GLOBAL_TRUE@ ${c_compatibility_srcdir}/fenv.h \
-@GLIBCXX_C_HEADERS_C_GLOBAL_TRUE@ ${c_compatibility_srcdir}/tgmath.h
+@GLIBCXX_C_HEADERS_C_GLOBAL_TRUE@ ${c_compatibility_srcdir}/tgmath.h \
+@GLIBCXX_C_HEADERS_C_GLOBAL_TRUE@ ${c_compatibility_srcdir}/math.h \
+@GLIBCXX_C_HEADERS_C_GLOBAL_TRUE@ ${c_compatibility_srcdir}/stdlib.h
@GLIBCXX_C_HEADERS_C_STD_TRUE@c_compatibility_headers =
@GLIBCXX_C_HEADERS_C_TRUE@c_compatibility_headers = \
diff --git a/libstdc++-v3/include/c_compatibility/math.h b/libstdc++-v3/include/c_compatibility/math.h
index 7617a31..67f5ef1 100644
--- a/libstdc++-v3/include/c_compatibility/math.h
+++ b/libstdc++-v3/include/c_compatibility/math.h
@@ -26,12 +26,15 @@
* This is a Standard C++ Library header.
*/
-#include <cmath>
#ifndef _GLIBCXX_MATH_H
#define _GLIBCXX_MATH_H 1
-#ifdef _GLIBCXX_NAMESPACE_C
+#if !defined __cplusplus || defined _GLIBCXX_INCLUDE_NEXT_C_HEADERS
+# include_next <math.h>
+#else
+# include <cmath>
+
using std::abs;
using std::acos;
using std::asin;
@@ -72,5 +75,4 @@ using std::isunordered;
#endif
#endif
-
#endif
diff --git a/libstdc++-v3/include/c_compatibility/stdlib.h b/libstdc++-v3/include/c_compatibility/stdlib.h
index bd666d6..bd72580 100644
--- a/libstdc++-v3/include/c_compatibility/stdlib.h
+++ b/libstdc++-v3/include/c_compatibility/stdlib.h
@@ -26,25 +26,37 @@
* This is a Standard C++ Library header.
*/
-#include <cstdlib>
-
#ifndef _GLIBCXX_STDLIB_H
#define _GLIBCXX_STDLIB_H 1
-#ifdef _GLIBCXX_NAMESPACE_C
+#if !defined __cplusplus || defined _GLIBCXX_INCLUDE_NEXT_C_HEADERS
+# include_next <stdlib.h>
+#else
+# include <cstdlib>
+
+using std::abort;
+using std::atexit;
+using std::exit;
+#if __cplusplus >= 201103L
+# ifdef _GLIBCXX_HAVE_AT_QUICK_EXIT
+ using std::at_quick_exit;
+# endif
+# ifdef _GLIBCXX_HAVE_QUICK_EXIT
+ using std::quick_exit;
+# endif
+#endif
+
+#if _GLIBCXX_HOSTED
using std::div_t;
using std::ldiv_t;
-using std::abort;
using std::abs;
-using std::atexit;
using std::atof;
using std::atoi;
using std::atol;
using std::bsearch;
using std::calloc;
using std::div;
-using std::exit;
using std::free;
using std::getenv;
using std::labs;
@@ -66,3 +78,4 @@ using std::wctomb;
#endif
#endif
+#endif
diff --git a/libstdc++-v3/include/c_global/cmath b/libstdc++-v3/include/c_global/cmath
index c689b31..45e40ab3 100644
--- a/libstdc++-v3/include/c_global/cmath
+++ b/libstdc++-v3/include/c_global/cmath
@@ -41,7 +41,9 @@
#include <bits/c++config.h>
#include <bits/cpp_type_traits.h>
#include <ext/type_traits.h>
-#include <math.h>
+#define _GLIBCXX_INCLUDE_NEXT_C_HEADERS
+#include_next <math.h>
+#undef _GLIBCXX_INCLUDE_NEXT_C_HEADERS
#ifndef _GLIBCXX_CMATH
#define _GLIBCXX_CMATH 1
diff --git a/libstdc++-v3/include/c_global/cstdlib b/libstdc++-v3/include/c_global/cstdlib
index 0f506a4..44b6e5c 100644
--- a/libstdc++-v3/include/c_global/cstdlib
+++ b/libstdc++-v3/include/c_global/cstdlib
@@ -69,7 +69,11 @@ namespace std
#else
-#include <stdlib.h>
+// Need to ensure this finds the C library's <stdlib.h> not a libstdc++
+// wrapper that might already be installed later in the include search path.
+#define _GLIBCXX_INCLUDE_NEXT_C_HEADERS
+#include_next <stdlib.h>
+#undef _GLIBCXX_INCLUDE_NEXT_C_HEADERS
// Get rid of those macros defined in <stdlib.h> in lieu of real functions.
#undef abort
diff --git a/libstdc++-v3/testsuite/26_numerics/headers/cmath/14608.cc b/libstdc++-v3/testsuite/26_numerics/headers/cmath/14608.cc
new file mode 100644
index 0000000..65f5c6c
--- /dev/null
+++ b/libstdc++-v3/testsuite/26_numerics/headers/cmath/14608.cc
@@ -0,0 +1,38 @@
+// Copyright (C) 2016 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 3, 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 COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++11" }
+// { dg-do compile }
+
+#include <cmath>
+// Also make names from <cmath> available in the global namespace:
+#include <math.h>
+
+bool foo(double d)
+{
+ return ::isfinite(d); // PR libstdc++/14608
+}
+
+int bar(double d)
+{
+ return ::signbit(d); // PR libstdc++/44611
+}
+
+constexpr bool is_double(double) { return true; }
+template<typename T> constexpr bool is_double(T) { return false; }
+using type = decltype(::abs(1.5));
+static_assert(is_double(type{}), "::abs(double) overload exists in <math.h>");
diff --git a/libstdc++-v3/testsuite/26_numerics/headers/cmath/c99_classification_macros_c.cc b/libstdc++-v3/testsuite/26_numerics/headers/cmath/c99_classification_macros_c.cc
index ead3018..cbced7d 100644
--- a/libstdc++-v3/testsuite/26_numerics/headers/cmath/c99_classification_macros_c.cc
+++ b/libstdc++-v3/testsuite/26_numerics/headers/cmath/c99_classification_macros_c.cc
@@ -17,12 +17,10 @@
// with this library; see the file COPYING3. If not see
// <http://www.gnu.org/licenses/>.
-// { dg-do compile }
+// { dg-do compile { xfail uclibc } }
+// { dg-excess-errors "" { target uclibc } }
// { dg-add-options no_pch }
-// { dg-xfail-if "" { { *-*-linux* *-*-gnu* *-*-darwin* *-*-solaris2.1[01]* hppa*-*-hpux* *-*-mingw* *-*-aix* } || { uclibc || newlib } } { "*" } { "" } }
-// { dg-excess-errors "" { target { { *-*-linux* *-*-gnu* *-*-darwin* *-*-solaris2.1[01]* hppa*-*-hpux* *-*-mingw* *-*-aix* } || { uclibc || newlib } } } }
-
#include <math.h>
void fpclassify() { }
diff --git a/libstdc++-v3/testsuite/26_numerics/headers/cstdlib/60401.cc b/libstdc++-v3/testsuite/26_numerics/headers/cstdlib/60401.cc
new file mode 100644
index 0000000..f0cff33
--- /dev/null
+++ b/libstdc++-v3/testsuite/26_numerics/headers/cstdlib/60401.cc
@@ -0,0 +1,28 @@
+// Copyright (C) 2016 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 3, 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 COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++11" }
+// { dg-do compile }
+
+// PR libstdc++/60401
+
+#include <stdlib.h>
+
+constexpr bool is_long(long) { return true; }
+template<typename T> constexpr bool is_long(T) { return false; }
+using type = decltype(::abs(1L));
+static_assert(is_long(type{}), "::abs(long) overload exists in <stdlib.h>");