In C++17 <math.h> should not put special functions in global namespace
authorJonathan Wakely <jwakely@redhat.com>
Thu, 21 Mar 2019 14:03:56 +0000 (14:03 +0000)
committerJonathan Wakely <redi@gcc.gnu.org>
Thu, 21 Mar 2019 14:03:56 +0000 (14:03 +0000)
IS 29124 8.2 [sf.mathh] says that <math.h> should add the names of the
special functions to the global namespace.  However, C++17 Annex D
[depr.c.headers] excludes those functions explicitly, so they should not
be placed in the global namespace unconditionally for C++17.

Only add them to the global namespace when IS 29124 is explicitly
requested via the __STDCPP_WANT_MATH_SPEC_FUNCS__ macro.

* include/c_compatibility/math.h [!__STDCPP_WANT_MATH_SPEC_FUNCS__]
(assoc_laguerre, assoc_laguerref, assoc_laguerrel, assoc_legendre)
(assoc_legendref, assoc_legendrel, beta, betaf, betal, comp_ellint_1)
(comp_ellint_1f, comp_ellint_1l, comp_ellint_2, comp_ellint_2f)
(comp_ellint_2l, comp_ellint_3, comp_ellint_3f, comp_ellint_3l)
(cyl_bessel_i, cyl_bessel_if, cyl_bessel_il, cyl_bessel_j)
(cyl_bessel_jf, cyl_bessel_jl, cyl_bessel_k, cyl_bessel_kf)
(cyl_bessel_kl, cyl_neumann, cyl_neumannf, cyl_neumannl, ellint_1)
(ellint_1f, ellint_1l, ellint_2, ellint_2f, ellint_2l, ellint_3)
(ellint_3f, ellint_3l, expint, expintf, expintl, hermite, hermitef)
(hermitel, laguerre, laguerref, laguerrel, legendre, legendref)
(legendrel, riemann_zeta, riemann_zetaf, riemann_zetal, sph_bessel)
(sph_besself, sph_bessell, sph_legendre, sph_legendref, sph_legendrel)
(sph_neumann, sph_neumannf, sph_neumannl): Only add using-declarations
when the special functions IS is enabled, not for C++17.
* testsuite/26_numerics/headers/cmath/functions_global_c++17.cc:
Replace with ...
* testsuite/26_numerics/headers/cmath/functions_global.cc: New test,
without checks for special functions in C++17.
* testsuite/26_numerics/headers/cmath/special_functions_global.cc:
New test.

From-SVN: r269837

libstdc++-v3/ChangeLog
libstdc++-v3/include/c_compatibility/math.h
libstdc++-v3/testsuite/26_numerics/headers/cmath/functions_global.cc [new file with mode: 0644]
libstdc++-v3/testsuite/26_numerics/headers/cmath/functions_global_c++17.cc [deleted file]
libstdc++-v3/testsuite/26_numerics/headers/cmath/special_functions_global.cc [new file with mode: 0644]

index 2daa699..dad1e54 100644 (file)
@@ -1,5 +1,27 @@
 2019-03-21  Jonathan Wakely  <jwakely@redhat.com>
 
+       * include/c_compatibility/math.h [!__STDCPP_WANT_MATH_SPEC_FUNCS__]
+       (assoc_laguerre, assoc_laguerref, assoc_laguerrel, assoc_legendre)
+       (assoc_legendref, assoc_legendrel, beta, betaf, betal, comp_ellint_1)
+       (comp_ellint_1f, comp_ellint_1l, comp_ellint_2, comp_ellint_2f)
+       (comp_ellint_2l, comp_ellint_3, comp_ellint_3f, comp_ellint_3l)
+       (cyl_bessel_i, cyl_bessel_if, cyl_bessel_il, cyl_bessel_j)
+       (cyl_bessel_jf, cyl_bessel_jl, cyl_bessel_k, cyl_bessel_kf)
+       (cyl_bessel_kl, cyl_neumann, cyl_neumannf, cyl_neumannl, ellint_1)
+       (ellint_1f, ellint_1l, ellint_2, ellint_2f, ellint_2l, ellint_3)
+       (ellint_3f, ellint_3l, expint, expintf, expintl, hermite, hermitef)
+       (hermitel, laguerre, laguerref, laguerrel, legendre, legendref)
+       (legendrel, riemann_zeta, riemann_zetaf, riemann_zetal, sph_bessel)
+       (sph_besself, sph_bessell, sph_legendre, sph_legendref, sph_legendrel)
+       (sph_neumann, sph_neumannf, sph_neumannl): Only add using-declarations
+       when the special functions IS is enabled, not for C++17.
+       * testsuite/26_numerics/headers/cmath/functions_global_c++17.cc:
+       Replace with ...
+       * testsuite/26_numerics/headers/cmath/functions_global.cc: New test,
+       without checks for special functions in C++17.
+       * testsuite/26_numerics/headers/cmath/special_functions_global.cc:
+       New test.
+
        PR libstdc++/88066
        * include/backward/hash_map: Use <> for includes not "".
        * include/backward/hash_set: Likewise.
index d9fe94c..7e8dab0 100644 (file)
@@ -111,7 +111,9 @@ using std::tgamma;
 using std::trunc;
 #endif // C++11 && _GLIBCXX_USE_C99_MATH_TR1
 
-#if _GLIBCXX_USE_STD_SPEC_FUNCS
+// The mathematical special functions are only added to the global namespace
+// by IS 29124, but not by C++17.
+#if __cplusplus >= 201103L && __STDCPP_WANT_MATH_SPEC_FUNCS__ != 0
 using std::assoc_laguerref;
 using std::assoc_laguerrel;
 using std::assoc_laguerre;
diff --git a/libstdc++-v3/testsuite/26_numerics/headers/cmath/functions_global.cc b/libstdc++-v3/testsuite/26_numerics/headers/cmath/functions_global.cc
new file mode 100644 (file)
index 0000000..19bcba9
--- /dev/null
@@ -0,0 +1,46 @@
+// Copyright (C) 2017-2019 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-do compile }
+
+#include <math.h>
+
+namespace gnu
+{
+  using ::acos;
+  using ::asin;
+  using ::atan;
+  using ::atan2;
+  using ::ceil;
+  using ::cos;
+  using ::cosh;
+  using ::exp;
+  using ::fabs;
+  using ::floor;
+  using ::fmod;
+  using ::frexp;
+  using ::ldexp;
+  using ::log;
+  using ::log10;
+  using ::modf;
+  using ::pow;
+  using ::sin;
+  using ::sinh;
+  using ::sqrt;
+  using ::tan;
+  using ::tanh;
+}
diff --git a/libstdc++-v3/testsuite/26_numerics/headers/cmath/functions_global_c++17.cc b/libstdc++-v3/testsuite/26_numerics/headers/cmath/functions_global_c++17.cc
deleted file mode 100644 (file)
index 8c4a06b..0000000
+++ /dev/null
@@ -1,111 +0,0 @@
-// Copyright (C) 2017-2019 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++17" }
-// { dg-do compile }
-
-#include <math.h>
-
-namespace gnu
-{
-  using ::acos;
-  using ::asin;
-  using ::atan;
-  using ::atan2;
-  using ::ceil;
-  using ::cos;
-  using ::cosh;
-  using ::exp;
-  using ::fabs;
-  using ::floor;
-  using ::fmod;
-  using ::frexp;
-  using ::ldexp;
-  using ::log;
-  using ::log10;
-  using ::modf;
-  using ::pow;
-  using ::sin;
-  using ::sinh;
-  using ::sqrt;
-  using ::tan;
-  using ::tanh;
-
-  using ::assoc_laguerre;
-  using ::assoc_laguerref;
-  using ::assoc_laguerrel;
-  using ::assoc_legendre;
-  using ::assoc_legendref;
-  using ::assoc_legendrel;
-  using ::beta;
-  using ::betaf;
-  using ::betal;
-  using ::comp_ellint_1;
-  using ::comp_ellint_1f;
-  using ::comp_ellint_1l;
-  using ::comp_ellint_2;
-  using ::comp_ellint_2f;
-  using ::comp_ellint_2l;
-  using ::comp_ellint_3;
-  using ::comp_ellint_3f;
-  using ::comp_ellint_3l;
-  using ::cyl_bessel_i;
-  using ::cyl_bessel_if;
-  using ::cyl_bessel_il;
-  using ::cyl_bessel_j;
-  using ::cyl_bessel_jf;
-  using ::cyl_bessel_jl;
-  using ::cyl_bessel_k;
-  using ::cyl_bessel_kf;
-  using ::cyl_bessel_kl;
-  using ::cyl_neumann;
-  using ::cyl_neumannf;
-  using ::cyl_neumannl;
-  using ::ellint_1;
-  using ::ellint_1f;
-  using ::ellint_1l;
-  using ::ellint_2;
-  using ::ellint_2f;
-  using ::ellint_2l;
-  using ::ellint_3;
-  using ::ellint_3f;
-  using ::ellint_3l;
-  using ::expint;
-  using ::expintf;
-  using ::expintl;
-  using ::hermite;
-  using ::hermitef;
-  using ::hermitel;
-  using ::laguerre;
-  using ::laguerref;
-  using ::laguerrel;
-  using ::legendre;
-  using ::legendref;
-  using ::legendrel;
-  using ::riemann_zeta;
-  using ::riemann_zetaf;
-  using ::riemann_zetal;
-  using ::sph_bessel;
-  using ::sph_besself;
-  using ::sph_bessell;
-  using ::sph_legendre;
-  using ::sph_legendref;
-  using ::sph_legendrel;
-  using ::sph_neumann;
-  using ::sph_neumannf;
-  using ::sph_neumannl;
-}
diff --git a/libstdc++-v3/testsuite/26_numerics/headers/cmath/special_functions_global.cc b/libstdc++-v3/testsuite/26_numerics/headers/cmath/special_functions_global.cc
new file mode 100644 (file)
index 0000000..d8afe4a
--- /dev/null
@@ -0,0 +1,165 @@
+// Copyright (C) 2019 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++17" }
+// { dg-do compile }
+
+#undef __STDCPP_WANT_MATH_SPEC_FUNCS__
+#define __STDCPP_WANT_MATH_SPEC_FUNCS__ 0
+#include <math.h>
+
+struct R { };
+
+// When __STDCPP_WANT_MATH_SPEC_FUNCS__ == 0, none of these names should be
+// declared in the global namespace by <math.h>. Calls to them should find
+// the overloads declared in this file, not the ones that are present in
+// namespace std for C++17 and later.
+
+R assoc_laguerre(...);
+R assoc_laguerref(...);
+R assoc_laguerrel(...);
+R assoc_legendre(...);
+R assoc_legendref(...);
+R assoc_legendrel(...);
+R beta(...);
+R betaf(...);
+R betal(...);
+R comp_ellint_1(...);
+R comp_ellint_1f(...);
+R comp_ellint_1l(...);
+R comp_ellint_2(...);
+R comp_ellint_2f(...);
+R comp_ellint_2l(...);
+R comp_ellint_3(...);
+R comp_ellint_3f(...);
+R comp_ellint_3l(...);
+R cyl_bessel_i(...);
+R cyl_bessel_if(...);
+R cyl_bessel_il(...);
+R cyl_bessel_j(...);
+R cyl_bessel_jf(...);
+R cyl_bessel_jl(...);
+R cyl_bessel_k(...);
+R cyl_bessel_kf(...);
+R cyl_bessel_kl(...);
+R cyl_neumann(...);
+R cyl_neumannf(...);
+R cyl_neumannl(...);
+R ellint_1(...);
+R ellint_1f(...);
+R ellint_1l(...);
+R ellint_2(...);
+R ellint_2f(...);
+R ellint_2l(...);
+R ellint_3(...);
+R ellint_3f(...);
+R ellint_3l(...);
+R expint(...);
+R expintf(...);
+R expintl(...);
+R hermite(...);
+R hermitef(...);
+R hermitel(...);
+R laguerre(...);
+R laguerref(...);
+R laguerrel(...);
+R legendre(...);
+R legendref(...);
+R legendrel(...);
+R riemann_zeta(...);
+R riemann_zetaf(...);
+R riemann_zetal(...);
+R sph_bessel(...);
+R sph_besself(...);
+R sph_bessell(...);
+R sph_legendre(...);
+R sph_legendref(...);
+R sph_legendrel(...);
+R sph_neumann(...);
+R sph_neumannf(...);
+R sph_neumannl(...);
+
+void
+test01()
+{
+  R r;
+  // Call each function with arguments matching the real special functions
+  // in namespace std, to verify that the overloads above are called instead.
+  r = assoc_laguerre(1u, 1u, 1.0);
+  r = assoc_laguerref(1u, 1u, 1.0f);
+  r = assoc_laguerrel(1u, 1u, 1.0l);
+  r = assoc_legendre(1u, 1u, 1.0);
+  r = assoc_legendref(1u, 1u, 1.0f);
+  r = assoc_legendrel(1u, 1u, 1.0l);
+  r = beta(1.0, 1.0);
+  r = betaf(1.0f, 1.0f);
+  r = betal(1.0l, 1.0l);
+  r = comp_ellint_1(1.0);
+  r = comp_ellint_1f(1.0f);
+  r = comp_ellint_1l(1.0l);
+  r = comp_ellint_2(1.0);
+  r = comp_ellint_2f(1.0f);
+  r = comp_ellint_2l(1.0l);
+  r = comp_ellint_3(1.0, 1.0);
+  r = comp_ellint_3f(1.0f, 1.0f);
+  r = comp_ellint_3l(1.0l, 1.0l);
+  r = cyl_bessel_i(1.0, 1.0);
+  r = cyl_bessel_if(1.0f, 1.0f);
+  r = cyl_bessel_il(1.0l, 1.0l);
+  r = cyl_bessel_j(1.0, 1.0);
+  r = cyl_bessel_jf(1.0f, 1.0f);
+  r = cyl_bessel_jl(1.0l, 1.0l);
+  r = cyl_bessel_k(1.0, 1.0);
+  r = cyl_bessel_kf(1.0f, 1.0f);
+  r = cyl_bessel_kl(1.0l, 1.0l);
+  r = cyl_neumann(1.0, 1.0);
+  r = cyl_neumannf(1.0f, 1.0f);
+  r = cyl_neumannl(1.0l, 1.0l);
+  r = ellint_1(1.0, 1.0);
+  r = ellint_1f(1.0f, 1.0f);
+  r = ellint_1l(1.0l, 1.0l);
+  r = ellint_2(1.0, 1.0);
+  r = ellint_2f(1.0f, 1.0f);
+  r = ellint_2l(1.0l, 1.0l);
+  r = ellint_3(1.0, 1.0, 1.0);
+  r = ellint_3f(1.0f, 1.0f, 1.0f);
+  r = ellint_3l(1.0l, 1.0l, 1.0l);
+  r = expint(1.0);
+  r = expintf(1.0f);
+  r = expintl(1.0l);
+  r = hermite(1u, 1.0);
+  r = hermitef(1u, 1.0f);
+  r = hermitel(1u, 1.0l);
+  r = laguerre(1u, 1.0);
+  r = laguerref(1u, 1.0f);
+  r = laguerrel(1u, 1.0l);
+  r = legendre(1u, 1.0);
+  r = legendref(1u, 1.0f);
+  r = legendrel(1u, 1.0l);
+  r = riemann_zeta(1.0);
+  r = riemann_zetaf(1.0f);
+  r = riemann_zetal(1.0l);
+  r = sph_bessel(1u, 1.0);
+  r = sph_besself(1u, 1.0f);
+  r = sph_bessell(1u, 1.0l);
+  r = sph_legendre(1u, 1u, 1.0);
+  r = sph_legendref(1u, 1u, 1.0f);
+  r = sph_legendrel(1u, 1u, 1.0l);
+  r = sph_neumann(1u, 1.0);
+  r = sph_neumannf(1u, 1.0f);
+  r = sph_neumannl(1u, 1.0l);
+}