1 // RUN: %clang_cc1 -emit-llvm-only -verify -std=c++11 %s
5 typedef Foo Bar
; // expected-note{{type 'Bar' (aka 'Foo') found by destructor name lookup}}
14 typedef int OtherInteger
;
18 void cv_test(const volatile T
* cvt
) {
19 cvt
->T::~T(); // no-warning
22 void f(A
* a
, Foo
*f
, int *i
, double *d
, int ii
) {
26 a
->~foo(); // expected-error{{undeclared identifier 'foo' in destructor name}}
28 a
->~Bar(); // expected-error{{destructor type 'Bar' (aka 'Foo') in object destruction expression does not match the type 'A' of the object being destroyed}}
32 i
->~Bar(); // expected-error{{does not match}}
34 g().~Bar(); // expected-error{{non-scalar}}
36 f
->::~Bar(); // expected-error {{not a structure or union}}
38 f
->N::~Wibble(); // expected-error{{'N' does not refer to a type}} expected-error{{'Wibble' does not refer to a type}}
40 f
->Bar::~Bar(17, 42); // expected-error{{cannot have any arguments}}
43 i
->Integer::~Integer();
44 i
->N::~OtherInteger(); // expected-error{{'N' does not refer to a type name in pseudo-destructor expression; expected the name of type 'int'}}
45 // expected-error@-1{{'OtherInteger' does not refer to a type name in pseudo-destructor expression; expected the name of type 'int'}}
46 i
->N::OtherInteger::~OtherInteger();
47 i
->N::OtherInteger::~OtherInteger();
48 i
->N::OtherInteger::~Integer(); // expected-error{{'Integer' does not refer to a type name in pseudo-destructor expression; expected the name of type 'int'}}
49 i
->N::~Integer(); // expected-error{{'N' does not refer to a type name in pseudo-destructor expression; expected the name of type 'int'}}
50 i
->N::OtherInteger::~Integer(); // expected-error{{'Integer' does not refer to a type name in pseudo-destructor expression; expected the name of type 'int'}}
51 i
->Integer::~Double(); // expected-error{{the type of object expression ('int') does not match the type being destroyed ('Double' (aka 'double')) in pseudo-destructor expression}}
53 ii
->~Integer(); // expected-error{{member reference type 'int' is not a pointer; did you mean to use '.'?}}
65 void destroy_without_call(int *ip
) {
66 ip
->~Integer
; // expected-error{{reference to pseudo-destructor must be called}}
69 void paren_destroy_with_call(int *ip
) {
78 void test_X0(N1::X0
&x0
) {
86 p
->~oops(); // expected-error{{undeclared identifier 'oops' in destructor name}}
89 template void destroy(int*); // expected-note{{in instantiation of function template specialization}}
92 template<typename T
> using Id
= T
;
93 void AliasTemplate(int *p
) {
95 p
->template ~Id
<int>(); // expected-error {{'template' keyword not permitted in destructor name}}
97 (0).template ~Id
<int>(); // expected-error {{'template' keyword not permitted in destructor name}}
100 namespace dotPointerAccess
{
105 struct Derived
: Base
{
111 static_cast<Base
*>(&d
).~Base(); // expected-error {{member reference type 'Base *' is a pointer; did you mean to use '->'}}
112 d
->~Derived(); // expected-error {{member reference type 'Derived' is not a pointer; did you mean to use '.'}}
115 typedef Derived
*Foo
;
118 d
.~Foo(); // This is ok
119 d
.~Derived(); // expected-error {{member reference type 'Foo' (aka 'dotPointerAccess::Derived *') is a pointer; did you mean to use '->'}}
123 int pr45294
= 1 .~undeclared_tempate_name
<>(); // expected-error {{use of undeclared 'undeclared_tempate_name'}}
125 namespace TwoPhaseLookup
{
126 namespace NonTemplate
{
129 template<typename T
> void f(T
*p
) { p
->~G(); } // expected-error {{no member named '~Y'}}
130 void h1(Y
*p
) { p
->~G(); }
131 void h2(Y
*p
) { f(p
); }
132 namespace N
{ struct G
{}; }
133 void h3(N::G
*p
) { p
->~G(); }
134 void h4(N::G
*p
) { f(p
); } // expected-note {{instantiation of}}
137 namespace NonTemplateUndeclared
{
139 template<typename T
> void f(T
*p
) { p
->~G(); } // expected-error {{undeclared identifier 'G' in destructor name}}
141 void h1(Y
*p
) { p
->~G(); }
142 void h2(Y
*p
) { f(p
); } // expected-note {{instantiation of}}
143 namespace N
{ struct G
{}; }
144 void h3(N::G
*p
) { p
->~G(); }
145 void h4(N::G
*p
) { f(p
); }
149 template<typename T
> struct Y
{};
150 template<class U
> using G
= Y
<U
>;
151 template<typename T
> void f(T
*p
) { p
->~G
<int>(); } // expected-error {{no member named '~Y'}}
152 void h1(Y
<int> *p
) { p
->~G
<int>(); }
153 void h2(Y
<int> *p
) { f(p
); }
154 namespace N
{ template<typename T
> struct G
{}; }
155 void h3(N::G
<int> *p
) { p
->~G
<int>(); }
156 void h4(N::G
<int> *p
) { f(p
); } // expected-note {{instantiation of}}
159 namespace TemplateUndeclared
{
160 template<typename T
> struct Y
{};
161 // FIXME: Formally, this is ill-formed before we hit any instantiation,
162 // because we aren't supposed to treat the '<' as introducing a template
164 template<typename T
> void f(T
*p
) { p
->~G
<int>(); } // expected-error {{no member named 'G'}}
165 template<class U
> using G
= Y
<U
>;
166 void h1(Y
<int> *p
) { p
->~G
<int>(); }
167 void h2(Y
<int> *p
) { f(p
); } // expected-note {{instantiation of}}
168 namespace N
{ template<typename T
> struct G
{}; }
169 void h3(N::G
<int> *p
) { p
->~G
<int>(); }
170 void h4(N::G
<int> *p
) { f(p
); }
173 namespace TemplateNamesNonTemplate
{
174 int A
; // expected-note 2{{non-template here}}
175 template<typename
> int B
; // expected-note 2{{variable template 'B' declared here}} expected-warning {{extension}}
176 using C
= int; // expected-note 2{{non-template here}}
178 template<typename T
> void f1(int *p
) { p
->~A
<int>(); } // expected-error {{'A' does not refer to a template}}
179 template<typename T
> void f2(int *p
) { p
->~B
<int>(); } // expected-error {{template name refers to non-type template 'B'}}
180 template<typename T
> void f3(int *p
) { p
->~C
<int>(); } // expected-error {{'C' does not refer to a template}}
181 template<typename T
> void f4(int *p
) { p
->TemplateNamesNonTemplate::C::~A
<int>(); } // expected-error {{'A' does not refer to a template}}
182 template<typename T
> void f5(int *p
) { p
->TemplateNamesNonTemplate::C::~B
<int>(); } // expected-error {{template name refers to non-type template 'TemplateNamesNonTemplate::B'}}
183 template<typename T
> void f6(int *p
) { p
->TemplateNamesNonTemplate::C::~C
<int>(); } // expected-error {{'C' does not refer to a template}}
187 void destroy_array_element() {
190 arr
->~T(); // ok, destroy arr[0].
193 void destroy_function() {
195 destroy_function
->~T(); // expected-error {{object expression of non-scalar type 'void ()' cannot be used in a pseudo-destructor expression}}