OSDN Git Service

Backport from mainline
authorredi <redi@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 19 Dec 2011 01:49:08 +0000 (01:49 +0000)
committerredi <redi@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 19 Dec 2011 01:49:08 +0000 (01:49 +0000)
2011-11-13  Paolo Carlini  <paolo.carlini@oracle.com>

* include/c_global/cmath (atan2, pow): Simplify constraining on the
return type.

Backport from mainline
2011-11-12  Jonathan Wakely  <jwakely.gcc@gmail.com>

PR libstdc++/51083
* include/ext/type_traits.h (__promote): Only define __type member
for integral and floating point types, to prevent math functions
participating in overload resolution for other types.
(__promote_2, __promote_3, __promote_4): Use __promote in default
template argument values, so deduction only succeeds for integral and
floating point types.
* testsuite/26_numerics/cmath/51083.cc: New.
* testsuite/26_numerics/complex/51083.cc: New.
* testsuite/tr1/8_c_compatibility/cmath/51083.cc: New.
* testsuite/tr1/8_c_compatibility/complex/51083.cc: New.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/gcc-4_6-branch@182468 138bc75d-0d04-0410-961f-82ee72b054a4

libstdc++-v3/ChangeLog
libstdc++-v3/include/c_global/cmath
libstdc++-v3/include/ext/type_traits.h
libstdc++-v3/testsuite/26_numerics/cmath/51083.cc [new file with mode: 0644]
libstdc++-v3/testsuite/26_numerics/complex/51083.cc [new file with mode: 0644]
libstdc++-v3/testsuite/tr1/8_c_compatibility/cmath/51083.cc [new file with mode: 0644]
libstdc++-v3/testsuite/tr1/8_c_compatibility/complex/51083.cc [new file with mode: 0644]

index 5978d7b..153a5ce 100644 (file)
@@ -1,5 +1,28 @@
 2011-12-19  Jonathan Wakely  <jwakely.gcc@gmail.com>
 
+       Backport from mainline
+       2011-11-13  Paolo Carlini  <paolo.carlini@oracle.com>
+
+       * include/c_global/cmath (atan2, pow): Simplify constraining on the
+       return type.
+
+       Backport from mainline
+       2011-11-12  Jonathan Wakely  <jwakely.gcc@gmail.com>
+
+       PR libstdc++/51083
+       * include/ext/type_traits.h (__promote): Only define __type member
+       for integral and floating point types, to prevent math functions
+       participating in overload resolution for other types.
+       (__promote_2, __promote_3, __promote_4): Use __promote in default
+       template argument values, so deduction only succeeds for integral and
+       floating point types.
+       * testsuite/26_numerics/cmath/51083.cc: New.
+       * testsuite/26_numerics/complex/51083.cc: New.
+       * testsuite/tr1/8_c_compatibility/cmath/51083.cc: New.
+       * testsuite/tr1/8_c_compatibility/complex/51083.cc: New.
+
+2011-12-19  Jonathan Wakely  <jwakely.gcc@gmail.com>
+
        PR libstdc++/50862
        * include/std/condition_variable (condition_variable_any::wait): Fix
        deadlock and ensure _Lock::lock() is called on exit.
index a333eb5..764f342 100644 (file)
@@ -156,10 +156,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
   template<typename _Tp, typename _Up>
     inline
-    typename __gnu_cxx::__promote_2<
-    typename __gnu_cxx::__enable_if<__is_arithmetic<_Tp>::__value
-                                   && __is_arithmetic<_Up>::__value,
-                                   _Tp>::__type, _Up>::__type
+    typename __gnu_cxx::__promote_2<_Tp, _Up>::__type
     atan2(_Tp __y, _Up __x)
     {
       typedef typename __gnu_cxx::__promote_2<_Tp, _Up>::__type __type;
@@ -374,10 +371,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
   template<typename _Tp, typename _Up>
     inline
-    typename __gnu_cxx::__promote_2<
-    typename __gnu_cxx::__enable_if<__is_arithmetic<_Tp>::__value
-                                   && __is_arithmetic<_Up>::__value,
-                                   _Tp>::__type, _Up>::__type
+    typename __gnu_cxx::__promote_2<_Tp, _Up>::__type
     pow(_Tp __x, _Up __y)
     {
       typedef typename __gnu_cxx::__promote_2<_Tp, _Up>::__type __type;
index 9274726..b0fa36b 100644 (file)
@@ -161,44 +161,50 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     struct __promote
     { typedef double __type; };
 
+  // No nested __type member for non-integer non-floating point types,
+  // allows this type to be used for SFINAE to constrain overloads in
+  // <cmath> and <complex> to only the intended types.
   template<typename _Tp>
     struct __promote<_Tp, false>
-    { typedef _Tp __type; };
+    { };
+
+  template<>
+    struct __promote<long double>
+    { typedef long double __type; };
+
+  template<>
+    struct __promote<double>
+    { typedef double __type; };
+
+  template<>
+    struct __promote<float>
+    { typedef float __type; };
 
-  template<typename _Tp, typename _Up>
+  template<typename _Tp, typename _Up,
+           typename _Tp2 = typename __promote<_Tp>::__type,
+           typename _Up2 = typename __promote<_Up>::__type>
     struct __promote_2
     {
-    private:
-      typedef typename __promote<_Tp>::__type __type1;
-      typedef typename __promote<_Up>::__type __type2;
-
-    public:
-      typedef __typeof__(__type1() + __type2()) __type;
+      typedef __typeof__(_Tp2() + _Up2()) __type;
     };
 
-  template<typename _Tp, typename _Up, typename _Vp>
+  template<typename _Tp, typename _Up, typename _Vp,
+           typename _Tp2 = typename __promote<_Tp>::__type,
+           typename _Up2 = typename __promote<_Up>::__type,
+           typename _Vp2 = typename __promote<_Vp>::__type>
     struct __promote_3
     {
-    private:
-      typedef typename __promote<_Tp>::__type __type1;
-      typedef typename __promote<_Up>::__type __type2;
-      typedef typename __promote<_Vp>::__type __type3;
-
-    public:
-      typedef __typeof__(__type1() + __type2() + __type3()) __type;
+      typedef __typeof__(_Tp2() + _Up2() + _Vp2()) __type;
     };
 
-  template<typename _Tp, typename _Up, typename _Vp, typename _Wp>
+  template<typename _Tp, typename _Up, typename _Vp, typename _Wp,
+           typename _Tp2 = typename __promote<_Tp>::__type,
+           typename _Up2 = typename __promote<_Up>::__type,
+           typename _Vp2 = typename __promote<_Vp>::__type,
+           typename _Wp2 = typename __promote<_Wp>::__type>
     struct __promote_4
     {
-    private:
-      typedef typename __promote<_Tp>::__type __type1;
-      typedef typename __promote<_Up>::__type __type2;
-      typedef typename __promote<_Vp>::__type __type3;
-      typedef typename __promote<_Wp>::__type __type4;
-
-    public:
-      typedef __typeof__(__type1() + __type2() + __type3() + __type4()) __type;
+      typedef __typeof__(_Tp2() + _Up2() + _Vp2() + _Wp2()) __type;
     };
 
 _GLIBCXX_END_NAMESPACE_VERSION
diff --git a/libstdc++-v3/testsuite/26_numerics/cmath/51083.cc b/libstdc++-v3/testsuite/26_numerics/cmath/51083.cc
new file mode 100644 (file)
index 0000000..8ba9b10
--- /dev/null
@@ -0,0 +1,62 @@
+// { dg-options "-std=gnu++0x" }
+//
+// Copyright (C) 2011 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 <cmath>
+
+namespace a
+{
+  template<typename> class Mat { };
+
+  template<typename T> struct Mat2 : Mat<T> { };
+
+  template<typename T>
+    int fdim(Mat<T>) { return 1; }
+
+  template<typename T, typename U>
+    int floor(Mat<T>, U) { return 1; }
+  template<typename T, typename U>
+    int floor(T, Mat<U>) { return 1; }
+
+  template<typename T, typename U, typename V>
+    int fma(Mat<T>, U, V) { return 1; }
+  template<typename T, typename U, typename V>
+    int fma(T, Mat<U>, V) { return 1; }
+  template<typename T, typename U, typename V>
+    int fma(T, U, Mat<V>) { return 1; }
+}
+
+int main()
+{
+  int __attribute__((unused)) i;
+
+  using namespace std;
+
+  a::Mat2<double> c;
+  i = fdim(c);
+  i = floor(c, 0.);
+  i = floor(0., c);
+  i = floor(c, 1);
+  i = floor(1, c);
+  i = fma(c, 0., 1.);
+  i = fma(0., c, 1.);
+  i = fma(0., 1., c);
+  i = fma(c, 0., 1);
+  i = fma(0., c, 1);
+  i = fma(0., 1, c);
+}
diff --git a/libstdc++-v3/testsuite/26_numerics/complex/51083.cc b/libstdc++-v3/testsuite/26_numerics/complex/51083.cc
new file mode 100644 (file)
index 0000000..54e781b
--- /dev/null
@@ -0,0 +1,54 @@
+// { dg-options "-std=gnu++0x" }
+//
+// Copyright (C) 2011 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>
+
+namespace a
+{
+  template<typename> class Mat { };
+
+  template<typename T> struct Mat2 : Mat<T> { };
+
+  template<typename T> int arg(Mat<T>) { return 1; }
+  template<typename T> int conj(Mat<T>) { return 1; }
+  template<typename T> int imag(Mat<T>) { return 1; }
+  template<typename T> int norm(Mat<T>) { return 1; }
+  template<typename T> int proj(Mat<T>) { return 1; }
+  template<typename T> int real(Mat<T>) { return 1; }
+
+  template<typename T, typename U> int pow(Mat<T>, U) { return 1; }
+  template<typename T, typename U> int pow(T, Mat<U>) { return 1; }
+}
+
+int main()
+{
+  int __attribute__((unused)) i;
+
+  using namespace std;
+
+  a::Mat2< std::complex<double> > c;
+  i = arg(c);
+  i = conj(c);
+  i = imag(c);
+  i = norm(c);
+  i = proj(c);
+  i = real(c);
+  i = pow(std::complex<float>(), c);
+  i = pow(c, std::complex<float>());
+}
diff --git a/libstdc++-v3/testsuite/tr1/8_c_compatibility/cmath/51083.cc b/libstdc++-v3/testsuite/tr1/8_c_compatibility/cmath/51083.cc
new file mode 100644 (file)
index 0000000..504305a
--- /dev/null
@@ -0,0 +1,62 @@
+// { dg-options "-std=gnu++0x" }
+//
+// Copyright (C) 2011 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 <tr1/cmath>
+
+namespace a
+{
+  template<typename> class Mat { };
+
+  template<typename T> struct Mat2 : Mat<T> { };
+
+  template<typename T>
+    int fdim(Mat<T>) { return 1; }
+
+  template<typename T, typename U>
+    int floor(Mat<T>, U) { return 1; }
+  template<typename T, typename U>
+    int floor(T, Mat<U>) { return 1; }
+
+  template<typename T, typename U, typename V>
+    int fma(Mat<T>, U, V) { return 1; }
+  template<typename T, typename U, typename V>
+    int fma(T, Mat<U>, V) { return 1; }
+  template<typename T, typename U, typename V>
+    int fma(T, U, Mat<V>) { return 1; }
+}
+
+int main()
+{
+  int __attribute__((unused)) i;
+
+  using namespace std::tr1;
+
+  a::Mat2<double> c;
+  i = fdim(c);
+  i = floor(c, 0.);
+  i = floor(0., c);
+  i = floor(c, 1);
+  i = floor(1, c);
+  i = fma(c, 0., 1.);
+  i = fma(0., c, 1.);
+  i = fma(0., 1., c);
+  i = fma(c, 0., 1);
+  i = fma(0., c, 1);
+  i = fma(0., 1, c);
+}
diff --git a/libstdc++-v3/testsuite/tr1/8_c_compatibility/complex/51083.cc b/libstdc++-v3/testsuite/tr1/8_c_compatibility/complex/51083.cc
new file mode 100644 (file)
index 0000000..f41914e
--- /dev/null
@@ -0,0 +1,54 @@
+// { dg-options "-std=gnu++0x" }
+//
+// Copyright (C) 2011 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 <tr1/complex>
+
+namespace a
+{
+  template<typename> class Mat { };
+
+  template<typename T> struct Mat2 : Mat<T> { };
+
+  template<typename T> int arg(Mat<T>) { return 1; }
+  template<typename T> int conj(Mat<T>) { return 1; }
+  template<typename T> int imag(Mat<T>) { return 1; }
+  template<typename T> int norm(Mat<T>) { return 1; }
+  template<typename T> int proj(Mat<T>) { return 1; }
+  template<typename T> int real(Mat<T>) { return 1; }
+
+  template<typename T, typename U> int pow(Mat<T>, U) { return 1; }
+  template<typename T, typename U> int pow(T, Mat<U>) { return 1; }
+}
+
+int main()
+{
+  int __attribute__((unused)) i;
+
+  using namespace std::tr1;
+
+  a::Mat2< std::complex<double> > c;
+  i = arg(c);
+  i = conj(c);
+  i = imag(c);
+  i = norm(c);
+  i = proj(c);
+  i = real(c);
+  i = pow(std::complex<float>(), c);
+  i = pow(c, std::complex<float>());
+}