We implemented DR 1137 which changed the return types of proj and conj
on scalars, but then before the final C++11 standard DR 1522 reverted
that change, and we never implemented it. That means since GCC 4.5.0
we've been shipping non-conforming proj and conj functions.

This fixes the return types to match the standard, and adds some
missing constexpr on the real and imag overloads for scalars.

Since we're reverting the change from DR 1137 there's no reason to
name the test after that DR, so I'm moving it back to its original
name.

I'm also changing a test's { target c++14 } to c++11. It was
originally written to test std::complex in C++14 mode when the default
was gnu++98, so needed an explicit -std=gnu++14. Now that is the
default and so isn't needed, but there's no reason the test can't also
be used in C++11 mode.

        PR libstdc++/61791
        PR libstdc++/70607
        * include/std/complex (real(T), imag(T)): Add _GLIBCXX_CONSTEXPR.
        (proj(T), conj(T)): Change return types per DR 1522.
        * include/tr1/complex (conj): Remove overloads and use std::conj.
        * testsuite/26_numerics/complex/dr781_dr1137.cc: Rename to...
        * testsuite/26_numerics/complex/dr781.cc: ... this, and update.
        * testsuite/26_numerics/complex/value_operations/constexpr2.cc: Test
        real(T) and imag(T). Allow testing for C++11 too.

Tested powerpc64le-linux, committed to trunk.

commit 4fb1b36a299577fdf65008a9793fbaf66204f6a2
Author: Jonathan Wakely <jwak...@redhat.com>
Date:   Wed Jan 25 10:24:43 2017 +0000

    PR libstdc++/70607 make proj(T) and conj(T) return complex<T>
    
        PR libstdc++/61791
        PR libstdc++/70607
        * include/std/complex (real(T), imag(T)): Add _GLIBCXX_CONSTEXPR.
        (proj(T), conj(T)): Change return types per DR 1522.
        * include/tr1/complex (conj): Remove overloads and use std::conj.
        * testsuite/26_numerics/complex/dr781_dr1137.cc: Rename to...
        * testsuite/26_numerics/complex/dr781.cc: ... this, and update.
        * testsuite/26_numerics/complex/value_operations/constexpr2.cc: Test
        real(T) and imag(T). Allow testing for C++11 too.

diff --git a/libstdc++-v3/include/std/complex b/libstdc++-v3/include/std/complex
index 12b6e41..6342c98 100644
--- a/libstdc++-v3/include/std/complex
+++ b/libstdc++-v3/include/std/complex
@@ -1840,7 +1840,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     }
 
   template<typename _Tp>
-    inline typename __gnu_cxx::__promote<_Tp>::__type
+    _GLIBCXX_CONSTEXPR inline typename __gnu_cxx::__promote<_Tp>::__type
     imag(_Tp)
     { return _Tp(); }
 
@@ -1853,7 +1853,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     }
 
   template<typename _Tp>
-    inline typename __gnu_cxx::__promote<_Tp>::__type
+    _GLIBCXX_CONSTEXPR inline typename __gnu_cxx::__promote<_Tp>::__type
     real(_Tp __x)
     { return __x; }
 
@@ -1921,16 +1921,21 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     { return __complex_proj(__z); }
 #endif
 
-  // DR 1137.
   template<typename _Tp>
-    inline typename __gnu_cxx::__promote<_Tp>::__type
+    inline std::complex<typename __gnu_cxx::__promote<_Tp>::__type>
     proj(_Tp __x)
-    { return __x; }
+    {
+      typedef typename __gnu_cxx::__promote<_Tp>::__type __type;
+      return std::proj(std::complex<__type>(__x));
+    }
 
   template<typename _Tp>
-    inline typename __gnu_cxx::__promote<_Tp>::__type
+    inline std::complex<typename __gnu_cxx::__promote<_Tp>::__type>
     conj(_Tp __x)
-    { return __x; }
+    {
+      typedef typename __gnu_cxx::__promote<_Tp>::__type __type;
+      return std::complex<__type>(__x, -__type());
+    }
 
 _GLIBCXX_END_NAMESPACE_VERSION
 
diff --git a/libstdc++-v3/include/tr1/complex b/libstdc++-v3/include/tr1/complex
index 8624e55..06f9ab0 100644
--- a/libstdc++-v3/include/tr1/complex
+++ b/libstdc++-v3/include/tr1/complex
@@ -371,17 +371,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     }
 
   using std::arg;
-
-  template<typename _Tp>
-    inline std::complex<_Tp>
-    conj(const std::complex<_Tp>& __z)
-    { return std::conj(__z); }  
-
-  template<typename _Tp>
-    inline std::complex<typename __gnu_cxx::__promote<_Tp>::__type>
-    conj(_Tp __x)
-    { return __x; }
-
+  using std::conj;
   using std::imag;
   using std::norm;
   using std::polar;
diff --git a/libstdc++-v3/testsuite/26_numerics/complex/dr781.cc 
b/libstdc++-v3/testsuite/26_numerics/complex/dr781.cc
new file mode 100644
index 0000000..3fb6cd1
--- /dev/null
+++ b/libstdc++-v3/testsuite/26_numerics/complex/dr781.cc
@@ -0,0 +1,81 @@
+// { dg-do run { target c++11 } }
+// 2008-05-22  Paolo Carlini  <paolo.carl...@oracle.com>
+//
+// Copyright (C) 2008-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/>.
+
+#include <complex>
+#include <testsuite_hooks.h>
+#include <testsuite_tr1.h>
+
+// DR 781. std::complex should add missing C99 functions.
+// DR 1137. Return type of conj and proj.
+// 1522. conj specification is now nonsense
+void test01()
+{
+  using __gnu_test::check_ret_type;
+
+  typedef std::complex<float>       cmplx_f_type;
+  typedef std::complex<double>      cmplx_d_type;
+  typedef std::complex<long double> cmplx_ld_type;
+
+  const int          i1 = 1;
+  const float        f1 = 1.0f;
+  const double       d1 = 1.0;
+  const long double ld1 = 1.0l;
+
+  const cmplx_f_type  c_f1(f1, f1);
+  const cmplx_d_type  c_d1(d1, d1);
+  const cmplx_ld_type c_ld1(ld1, ld1);
+
+  check_ret_type<cmplx_f_type>(std::proj(c_f1));
+  check_ret_type<cmplx_d_type>(std::proj(c_d1));
+  check_ret_type<cmplx_ld_type>(std::proj(c_ld1));
+
+  check_ret_type<cmplx_f_type>(std::proj(f1));
+  check_ret_type<cmplx_d_type>(std::proj(d1));
+  check_ret_type<cmplx_d_type>(std::proj(i1));
+  check_ret_type<cmplx_ld_type>(std::proj(ld1));
+
+  VERIFY( std::proj(f1) == std::proj(cmplx_f_type(f1)) );
+  VERIFY( std::proj(d1) == std::proj(cmplx_d_type(d1)) );
+  VERIFY( std::proj(ld1) == std::proj(cmplx_ld_type(ld1)) );
+  VERIFY( std::proj(i1) == std::proj(double(i1)) );
+
+  check_ret_type<cmplx_f_type>(std::conj(c_f1));
+  check_ret_type<cmplx_d_type>(std::conj(c_d1));
+  check_ret_type<cmplx_ld_type>(std::conj(c_ld1));
+
+  check_ret_type<cmplx_f_type>(std::conj(f1));
+  check_ret_type<cmplx_d_type>(std::conj(d1));
+  check_ret_type<cmplx_d_type>(std::conj(i1));
+  check_ret_type<cmplx_ld_type>(std::conj(ld1));
+
+  VERIFY( std::conj(f1) == std::conj(cmplx_f_type(f1)) );
+  VERIFY( std::conj(d1) == std::conj(cmplx_d_type(d1)) );
+  VERIFY( std::conj(ld1) == std::conj(cmplx_ld_type(ld1)) );
+  VERIFY( std::conj(i1) == std::conj(double(i1)) );
+  VERIFY( std::signbit(std::conj(f1).imag()) );
+  VERIFY( std::signbit(std::conj(d1).imag()) );
+  VERIFY( std::signbit(std::conj(ld1).imag()) );
+}
+
+int main()
+{
+  test01();
+  return 0;
+}
diff --git a/libstdc++-v3/testsuite/26_numerics/complex/dr781_dr1137.cc 
b/libstdc++-v3/testsuite/26_numerics/complex/dr781_dr1137.cc
deleted file mode 100644
index 8612087..0000000
--- a/libstdc++-v3/testsuite/26_numerics/complex/dr781_dr1137.cc
+++ /dev/null
@@ -1,69 +0,0 @@
-// { dg-do run { target c++11 } }
-// 2008-05-22  Paolo Carlini  <paolo.carl...@oracle.com>
-//
-// Copyright (C) 2008-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/>.
-
-#include <complex>
-#include <testsuite_hooks.h>
-#include <testsuite_tr1.h>
-
-// DR 781. std::complex should add missing C99 functions.
-// DR 1137. Return type of conj and proj.
-void test01()
-{
-  using __gnu_test::check_ret_type;
-
-  typedef std::complex<float>       cmplx_f_type;
-  typedef std::complex<double>      cmplx_d_type;
-  typedef std::complex<long double> cmplx_ld_type;
-
-  const int          i1 = 1;
-  const float        f1 = 1.0f;
-  const double       d1 = 1.0;
-  const long double ld1 = 1.0l;
-
-  const cmplx_f_type  c_f1(f1, f1);
-  const cmplx_d_type  c_d1(d1, d1);
-  const cmplx_ld_type c_ld1(ld1, ld1);
-
-  check_ret_type<cmplx_f_type>(std::proj(c_f1));
-  check_ret_type<cmplx_d_type>(std::proj(c_d1));
-  check_ret_type<cmplx_ld_type>(std::proj(c_ld1));
-
-  check_ret_type<float>(std::proj(f1));
-  check_ret_type<double>(std::proj(d1));
-  check_ret_type<double>(std::proj(i1));
-  VERIFY( std::proj(i1) == std::proj(double(i1)) );
-  check_ret_type<long double>(std::proj(ld1));
-
-  check_ret_type<cmplx_f_type>(std::conj(c_f1));
-  check_ret_type<cmplx_d_type>(std::conj(c_d1));
-  check_ret_type<cmplx_ld_type>(std::conj(c_ld1));
-
-  check_ret_type<float>(std::conj(f1));
-  check_ret_type<double>(std::conj(d1));
-  check_ret_type<double>(std::conj(i1));
-  VERIFY( std::conj(i1) == std::conj(double(i1)) );
-  check_ret_type<long double>(std::conj(ld1));
-}
-
-int main()
-{
-  test01();
-  return 0;
-}
diff --git 
a/libstdc++-v3/testsuite/26_numerics/complex/value_operations/constexpr2.cc 
b/libstdc++-v3/testsuite/26_numerics/complex/value_operations/constexpr2.cc
index 94840ec..c6e91c2 100644
--- a/libstdc++-v3/testsuite/26_numerics/complex/value_operations/constexpr2.cc
+++ b/libstdc++-v3/testsuite/26_numerics/complex/value_operations/constexpr2.cc
@@ -1,4 +1,4 @@
-// { dg-do compile { target c++14 } }
+// { dg-do compile { target c++11 } }
 
 // Copyright (C) 2014-2017 Free Software Foundation, Inc.
 //
@@ -24,4 +24,6 @@ int main()
   constexpr std::complex<int> c{};
   constexpr auto r __attribute__((unused)) = real(c);
   constexpr auto i __attribute__((unused)) = imag(c);
+  constexpr double r2 __attribute__((unused)) = std::real(0.0);
+  constexpr double i2 __attribute__((unused)) = std::imag(0.0);
 }

Reply via email to