re PR libstdc++/51083 (TR1 [tr.c99.cmath.over] and C++11 [cmplx.over] overloads not constrained)

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.

From-SVN: r181321
This commit is contained in:
Jonathan Wakely 2011-11-12 15:57:03 +00:00 committed by Jonathan Wakely
parent 33a55f2919
commit 306133e3d4
6 changed files with 277 additions and 25 deletions

View File

@ -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

View 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<typename _Tp, typename _Up>
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,
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

View File

@ -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);
}

View File

@ -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>());
}

View File

@ -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);
}

View File

@ -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>());
}