diff mbox

libstdc++/14608 Add C++-conforming wrappers for stdlib.h and math.h

Message ID 20160119214359.GL15084@redhat.com
State New
Headers show

Commit Message

Jonathan Wakely Jan. 19, 2016, 9:43 p.m. UTC
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.

Comments

Dominik Vogt Jan. 20, 2016, 4:17 p.m. UTC | #1
On Tue, Jan 19, 2016 at 09:43:59PM +0000, Jonathan Wakely wrote:
> 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.

I think this fix is incomplete.  There are still some test errors
because of missing signatures in the Plumhall testsuite.  Please
check the information I've added to
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=60401

Ciao

Dominik ^_^  ^_^
diff mbox

Patch

commit 55b627c6c6b84fa05d01005bc7bff0860a280cc0
Author: Jonathan Wakely <jwakely@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>");