p10-0x.cpp revision 4db8c4483ea7b271bcce3a0312a0ac434313c09b
1// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
2
3// PR10127/N3031
4struct A { ~A(); };
5struct B {};
6template<typename T>
7void b(const T *x, const A *y) {
8  // FIXME: this parses as a pseudo destructor call which doesn't have decltype support yet
9  x->~decltype(T())(); // expected-error{{expected a class name after '~' to name a destructor}}
10
11  y->~decltype(*y)(); // expected-error{{destructor type 'decltype(*y)' (aka 'const A &') in object destruction expression does not match the type 'const A' of the object being destroyed}}
12  y->~decltype(T())(); // expected-error{{destructor type 'decltype(T())' in object destruction expression does not match the type 'const A' of the object being destroyed}}
13  y->~decltype(A())();
14}
15template void b(const int*, const A*);
16template void b(const A*,const A*);
17void a(const A *x) {
18  x->~decltype(A())();
19  x->~decltype(*x)(); // expected-error{{destructor type 'decltype(*x)' (aka 'const A &') in object destruction expression does not match the type 'const A' of the object being destroyed}}
20  x->~decltype()(); // expected-error{{expected expression}}
21  x->~decltype(B())(); // expected-error{{destructor type 'decltype(B())' (aka 'B') in object destruction expression does not match the type 'const A' of the object being destroyed}}
22  x->~decltype(x)(); // expected-error{{destructor type 'decltype(x)' (aka 'const A *') in object destruction expression does not match the type 'const A' of the object being destroyed}}
23  // this last one could be better, mentioning that the nested-name-specifier could be removed or a type name after the ~
24  x->::A::~decltype(*x)(); // expected-error{{expected a class name after '~' to name a destructor}}
25  y->~decltype(A())(); // expected-error{{use of undeclared identifier 'y'}}
26}
27