diff options
-rw-r--r-- | libstdc++-v3/ChangeLog | 14 | ||||
-rw-r--r-- | libstdc++-v3/include/ext/type_traits.h | 56 | ||||
-rw-r--r-- | libstdc++-v3/testsuite/26_numerics/cmath/51083.cc | 62 | ||||
-rw-r--r-- | libstdc++-v3/testsuite/26_numerics/complex/51083.cc | 54 | ||||
-rw-r--r-- | libstdc++-v3/testsuite/tr1/8_c_compatibility/cmath/51083.cc | 62 | ||||
-rw-r--r-- | libstdc++-v3/testsuite/tr1/8_c_compatibility/complex/51083.cc | 54 |
6 files changed, 277 insertions, 25 deletions
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 826ca44..22663da 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,17 @@ +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-11-10 Andrew MacLeod <amacleod@redhat.com> PR middle-end/51038 diff --git a/libstdc++-v3/include/ext/type_traits.h b/libstdc++-v3/include/ext/type_traits.h index 9274726..b0fa36b 100644 --- a/libstdc++-v3/include/ext/type_traits.h +++ b/libstdc++-v3/include/ext/type_traits.h @@ -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 index 0000000..8ba9b10 --- /dev/null +++ b/libstdc++-v3/testsuite/26_numerics/cmath/51083.cc @@ -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 index 0000000..54e781b --- /dev/null +++ b/libstdc++-v3/testsuite/26_numerics/complex/51083.cc @@ -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 index 0000000..504305a --- /dev/null +++ b/libstdc++-v3/testsuite/tr1/8_c_compatibility/cmath/51083.cc @@ -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 index 0000000..f41914e --- /dev/null +++ b/libstdc++-v3/testsuite/tr1/8_c_compatibility/complex/51083.cc @@ -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>()); +} |