PR libstdc++/82417 do not include C99 <complex.h> in strict modes

Message ID 20171010112844.GA28974@redhat.com
State New
Headers show
Series
  • PR libstdc++/82417 do not include C99 <complex.h> in strict modes
Related show

Commit Message

Jonathan Wakely Oct. 10, 2017, 11:28 a.m.
As an extension the C++ version of <complex.h> includes the C version,
but that defines macros with non-reserved names that should not be
defined in ISO C++. Only include the C header for non-strict modes, or
for pre-C++11 (because C++98 doesn't mention <complex.h> at all).

	PR libstdc++/59087
	PR libstdc++/82417
	* include/c_compatibility/complex.h [!C++98 && __STRICT_ANSI__]: Do
	not include C library's <complex.h>.
	* testsuite/26_numerics/complex/c99.cc: Depend on __STRICT_ANSI__.
	* testsuite/26_numerics/headers/complex.h/std_c++11.h: New test.
	* testsuite/26_numerics/headers/complex.h/std_gnu++11.h: New test.
	* testsuite/26_numerics/headers/complex.h/std_c++98.h: New test.

Tested powerpc64le-linux, committed to trunk.
commit fb0385e979610a025d4b42e0b78f54447c799946
Author: redi <redi@138bc75d-0d04-0410-961f-82ee72b054a4>
Date:   Tue Oct 10 11:25:45 2017 +0000

    PR libstdc++/82417 do not include C99 <complex.h> in strict modes
    
    As an extension the C++ version of <complex.h> includes the C version,
    but that defines macros with non-reserved names that should not be
    defined in ISO C++. Only include the C header for non-strict modes, or
    for pre-C++11 (because C++98 doesn't mention <complex.h> at all).
    
            PR libstdc++/59087
            PR libstdc++/82417
            * include/c_compatibility/complex.h [!C++98 && __STRICT_ANSI__]: Do
            not include C library's <complex.h>.
            * testsuite/26_numerics/complex/c99.cc: Depend on __STRICT_ANSI__.
            * testsuite/26_numerics/headers/complex.h/std_c++11.h: New test.
            * testsuite/26_numerics/headers/complex.h/std_gnu++11.h: New test.
            * testsuite/26_numerics/headers/complex.h/std_c++98.h: New test.
    
    git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@253581 138bc75d-0d04-0410-961f-82ee72b054a4

Patch

diff --git a/libstdc++-v3/include/c_compatibility/complex.h b/libstdc++-v3/include/c_compatibility/complex.h
index b9af8472562..4b2343926ef 100644
--- a/libstdc++-v3/include/c_compatibility/complex.h
+++ b/libstdc++-v3/include/c_compatibility/complex.h
@@ -32,7 +32,9 @@ 
 # include <ccomplex>
 #endif
 
-#if _GLIBCXX_HAVE_COMPLEX_H
+#if __cplusplus >= 201103L && defined(__STRICT_ANSI__)
+// For strict modes do not include the C library's <complex.h>, see PR 82417.
+#elif _GLIBCXX_HAVE_COMPLEX_H
 # include_next <complex.h>
 # ifdef _GLIBCXX_COMPLEX
 // See PR56111, keep the macro in C++03 if possible.
diff --git a/libstdc++-v3/testsuite/26_numerics/complex/c99.cc b/libstdc++-v3/testsuite/26_numerics/complex/c99.cc
index 70189627ca2..9b0def408c8 100644
--- a/libstdc++-v3/testsuite/26_numerics/complex/c99.cc
+++ b/libstdc++-v3/testsuite/26_numerics/complex/c99.cc
@@ -26,7 +26,8 @@ 
 
 int main()
 {
-#if _GLIBCXX_HAVE_COMPLEX_H
+#if _GLIBCXX_HAVE_COMPLEX_H && !defined(__STRICT_ANSI__)
+  // This is a GNU extension.
   double _Complex x = .5;
   double _Complex y = cacos (x);
   (void)y;
diff --git a/libstdc++-v3/testsuite/26_numerics/headers/complex.h/std_c++11.h b/libstdc++-v3/testsuite/26_numerics/headers/complex.h/std_c++11.h
new file mode 100644
index 00000000000..22d84b2f14e
--- /dev/null
+++ b/libstdc++-v3/testsuite/26_numerics/headers/complex.h/std_c++11.h
@@ -0,0 +1,33 @@ 
+// Copyright (C) 2017 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=c++11" }
+
+#include <complex.h>
+
+// Should be equivalent to #include <complex>
+template class std::complex<double>;
+
+#ifdef complex
+# error "'complex' is defined as a macro by <complex.h> for -std=c++11"
+#endif
+#ifdef imaginary
+# error "'imaginary' is defined as a macro by <complex.h> for -std=c++11"
+#endif
+#ifdef I
+# error "'I' is defined as a macro by <complex.h> for -std=c++11"
+#endif
diff --git a/libstdc++-v3/testsuite/26_numerics/headers/complex.h/std_c++98.h b/libstdc++-v3/testsuite/26_numerics/headers/complex.h/std_c++98.h
new file mode 100644
index 00000000000..62674466c3d
--- /dev/null
+++ b/libstdc++-v3/testsuite/26_numerics/headers/complex.h/std_c++98.h
@@ -0,0 +1,55 @@ 
+// Copyright (C) 2017 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=c++98" }
+
+#include <complex.h>
+
+// Should be equivalent to C99 <complex>, not C++ <complex>
+namespace std
+{
+  struct complex;
+}
+
+#if _GLIBCXX_HAVE_COMPLEX_H
+namespace test
+{
+  using ::cacos;
+  using ::casin;
+  using ::catan;
+  using ::ccos;
+  using ::csin;
+  using ::ctan;
+  using ::ccosh;
+  using ::csinh;
+  using ::ctanh;
+  using ::cexp;
+  using ::clog;
+  using ::cabs;
+  using ::cpow;
+  using ::csqrt;
+  using ::carg;
+  using ::cimag;
+  using ::conj;
+  using ::cproj;
+  using ::creal;
+}
+#endif
+
+#ifndef complex
+# error "'complex' is not defined as a macro by <complex.h> for -std=c++98"
+#endif
diff --git a/libstdc++-v3/testsuite/26_numerics/headers/complex.h/std_gnu++11.h b/libstdc++-v3/testsuite/26_numerics/headers/complex.h/std_gnu++11.h
new file mode 100644
index 00000000000..9110ae4ecb2
--- /dev/null
+++ b/libstdc++-v3/testsuite/26_numerics/headers/complex.h/std_gnu++11.h
@@ -0,0 +1,52 @@ 
+// Copyright (C) 2017 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" }
+
+#include <complex.h>
+
+// Should be equivalent to #include <complex>
+template class std::complex<double>;
+
+#if _GLIBCXX_HAVE_COMPLEX_H
+namespace test
+{
+  using ::cacos;
+  using ::casin;
+  using ::catan;
+  using ::ccos;
+  using ::csin;
+  using ::ctan;
+  using ::ccosh;
+  using ::csinh;
+  using ::ctanh;
+  using ::cexp;
+  using ::clog;
+  using ::cabs;
+  using ::cpow;
+  using ::csqrt;
+  using ::carg;
+  using ::cimag;
+  using ::conj;
+  using ::cproj;
+  using ::creal;
+}
+#endif
+
+#ifdef complex
+# error "'complex' is defined as a macro by <complex.h> for -std=gnu++11"
+#endif