diff options
author | Jason Merrill <jason@redhat.com> | 2012-08-30 22:50:28 -0400 |
---|---|---|
committer | Jason Merrill <jason@gcc.gnu.org> | 2012-08-30 22:50:28 -0400 |
commit | 2c905502202e55fc91c2a2c9a94c3ef286f52f73 (patch) | |
tree | 037fed94ca2a1f6f563da30fce47620ac45fcd05 /gcc/testsuite | |
parent | e467c9d25782edea98d2cd66956d5abb82e847e9 (diff) | |
download | gcc-2c905502202e55fc91c2a2c9a94c3ef286f52f73.zip gcc-2c905502202e55fc91c2a2c9a94c3ef286f52f73.tar.gz gcc-2c905502202e55fc91c2a2c9a94c3ef286f52f73.tar.bz2 |
re PR c++/50545 ([C++0x][DR 1172] SFINAE does not handle an explicit type conversion (functional notation) with a braced-init-list well if target type is not dependent)
PR c++/50545
PR c++/51222
* pt.c (instantiation_dependent_r): New.
(instantiation_dependent_expression_p): New.
(value_dependent_expression_p): Use it. SCOPE_REF is always dependent.
* semantics.c (finish_decltype_type): Use it.
* cp-tree.h: Declare it.
From-SVN: r190830
Diffstat (limited to 'gcc/testsuite')
-rw-r--r-- | gcc/testsuite/g++.dg/cpp0x/decltype40.C | 101 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp0x/decltype41.C | 43 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp0x/decltype42.C | 31 |
3 files changed, 175 insertions, 0 deletions
diff --git a/gcc/testsuite/g++.dg/cpp0x/decltype40.C b/gcc/testsuite/g++.dg/cpp0x/decltype40.C new file mode 100644 index 0000000..7933c95 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/decltype40.C @@ -0,0 +1,101 @@ +// PR c++/51222 +// { dg-options -std=c++11 } + +template<class T> +struct add_rref { + typedef T&& type; +}; + +template<> +struct add_rref<void> { + typedef void type; +}; + +template<class T> +typename add_rref<T>::type declval(); + +template<class T, class U, class = + decltype(::delete ::new T(declval<U>())) +> +auto f(int) -> char; + +template<class, class> +auto f(...) -> char(&)[2]; + +template<class T, class = + decltype(::delete ::new T()) +> +auto g(int) -> char; + +template<class> +auto g(...) -> char(&)[2]; + +template<class T, class U> +auto f2(int) -> decltype(::delete ::new T(declval<U>()), char()); + +template<class, class> +auto f2(...) -> char(&)[2]; + +template<class T> +auto g2(int) -> decltype(::delete ::new T(), char()); + +template<class> +auto g2(...) -> char(&)[2]; + +struct C { }; + +struct A { + virtual ~A() = 0; +}; + +struct D1 { + D1() = delete; +}; + +struct D2 { + ~D2() = delete; +}; + +static_assert(sizeof(g<void>(0)) == 2, "Ouch"); +static_assert(sizeof(g<void()>(0)) == 2, "Ouch"); +static_assert(sizeof(g<void() const>(0)) == 2, "Ouch"); +static_assert(sizeof(g<A>(0)) == 2, "Ouch"); +static_assert(sizeof(g<D1>(0)) == 2, "Ouch"); +static_assert(sizeof(g<D2>(0)) == 2, "Ouch"); +static_assert(sizeof(g<int&>(0)) == 2, "Ouch"); +static_assert(sizeof(g<int&&>(0)) == 2, "Ouch"); +static_assert(sizeof(g<void(&)()>(0)) == 2, "Ouch"); +static_assert(sizeof(g<void(&&)()>(0)) == 2, "Ouch"); +static_assert(sizeof(f<void, void>(0)) == 2, "Ouch"); +static_assert(sizeof(f<void(), void()>(0)) == 2, "Ouch"); +static_assert(sizeof(f<void() const, void() const>(0)) == 2, "Ouch"); +static_assert(sizeof(f<int, void>(0)) == 2, "Ouch"); +static_assert(sizeof(f<void, int>(0)) == 2, "Ouch"); +static_assert(sizeof(f<C, void>(0)) == 2, "Ouch"); +static_assert(sizeof(f<C, int>(0)) == 2, "Ouch"); +static_assert(sizeof(f<int&, int&>(0)) == 2, "Ouch"); +static_assert(sizeof(f<int&&, int&&>(0)) == 2, "Ouch"); +static_assert(sizeof(f<void(&)(), void(&)()>(0)) == 2, "Ouch"); +static_assert(sizeof(f<void(&&)(), void(&&)()>(0)) == 2, "Ouch"); + +static_assert(sizeof(g2<void>(0)) == 2, "Ouch"); +static_assert(sizeof(g2<void()>(0)) == 2, "Ouch"); +static_assert(sizeof(g2<void() const>(0)) == 2, "Ouch"); +static_assert(sizeof(g2<A>(0)) == 2, "Ouch"); +static_assert(sizeof(g2<D1>(0)) == 2, "Ouch"); +static_assert(sizeof(g2<D2>(0)) == 2, "Ouch"); +static_assert(sizeof(g2<int&>(0)) == 2, "Ouch"); +static_assert(sizeof(g2<int&&>(0)) == 2, "Ouch"); +static_assert(sizeof(g2<void(&)()>(0)) == 2, "Ouch"); +static_assert(sizeof(g2<void(&&)()>(0)) == 2, "Ouch"); +static_assert(sizeof(f2<void, void>(0)) == 2, "Ouch"); +static_assert(sizeof(f2<void(), void()>(0)) == 2, "Ouch"); +static_assert(sizeof(f2<void() const, void() const>(0)) == 2, "Ouch"); +static_assert(sizeof(f2<int, void>(0)) == 2, "Ouch"); +static_assert(sizeof(f2<void, int>(0)) == 2, "Ouch"); +static_assert(sizeof(f2<C, void>(0)) == 2, "Ouch"); +static_assert(sizeof(f2<C, int>(0)) == 2, "Ouch"); +static_assert(sizeof(f2<int&, int&>(0)) == 2, "Ouch"); +static_assert(sizeof(f2<int&&, int&&>(0)) == 2, "Ouch"); +static_assert(sizeof(f2<void(&)(), void(&)()>(0)) == 2, "Ouch"); +static_assert(sizeof(f2<void(&&)(), void(&&)()>(0)) == 2, "Ouch"); diff --git a/gcc/testsuite/g++.dg/cpp0x/decltype41.C b/gcc/testsuite/g++.dg/cpp0x/decltype41.C new file mode 100644 index 0000000..1439e15 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/decltype41.C @@ -0,0 +1,43 @@ +// Core 1273 +// { dg-do compile { target c++11 } } + +template <class T> struct C; +template <class T> struct D; + +class A +{ + int i; + static int j; + friend struct C<int>; + friend struct D<int>; +} a; + +class B +{ + int i; + static int j; + friend struct C<float>; + friend struct D<float>; +} b; + +template <class T> +struct C +{ + template <class U> decltype (a.i) f() { } // #1 + template <class U> decltype (b.i) f() { } // #2 +}; + +template <class T> +struct D +{ + template <class U> decltype (A::j) f() { } // #1 + template <class U> decltype (B::j) f() { } // #2 +}; + +int main() +{ + C<int>().f<int>(); // calls #1 + C<float>().f<float>(); // calls #2 + D<int>().f<int>(); // calls #1 + D<float>().f<float>(); // calls #2 +} diff --git a/gcc/testsuite/g++.dg/cpp0x/decltype42.C b/gcc/testsuite/g++.dg/cpp0x/decltype42.C new file mode 100644 index 0000000..6c1aa43 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/decltype42.C @@ -0,0 +1,31 @@ +// PR c++/50545 +// { dg-do compile { target c++11 } } + +template< class T > +T&& declval(); + +// #1 +template< class T > +auto f( int ) + -> decltype( int{ declval<T>() } ); + +// #2 +template< class > +void f( ... ); + + +#define STATIC_ASSERT( ... ) static_assert( __VA_ARGS__, #__VA_ARGS__ ) + +template< class T, class U > +struct is_same { + static constexpr bool value = false; +}; + +template< class T > +struct is_same<T, T> { + static constexpr bool value = true; +}; + + +STATIC_ASSERT( is_same< decltype( f<int>(0) ), int >::value ); // OK; f<int>(0) calls #1. +STATIC_ASSERT( is_same< decltype( f<int*>(0) ), void >::value ); // static assertion fails; f<int*>(0) should call #2, because int{ (int*)0 } is ill-formed, but calls #1. |