1d6537015745128064dc12fcc06af65372dfd5da9Richard Smith// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
22cf738f1944d1cc724ea7561b84440a3a1059e45Anders Carlssonstruct A {};
32cf738f1944d1cc724ea7561b84440a3a1059e45Anders Carlsson
42cf738f1944d1cc724ea7561b84440a3a1059e45Anders Carlssonenum Foo { F };
57ec1873d694cf870264694d2b61219a03492bc30Douglas Gregortypedef Foo Bar; // expected-note{{type 'Bar' (aka 'Foo') is declared here}}
62cf738f1944d1cc724ea7561b84440a3a1059e45Anders Carlsson
7a71d819bb8f50c28938db0f2867d3fb6e2ce5910Douglas Gregortypedef int Integer;
8b10cd04880672103660e5844e51ee91af7361a20Douglas Gregortypedef double Double;
9a71d819bb8f50c28938db0f2867d3fb6e2ce5910Douglas Gregor
10a71d819bb8f50c28938db0f2867d3fb6e2ce5910Douglas Gregorvoid g();
11a71d819bb8f50c28938db0f2867d3fb6e2ce5910Douglas Gregor
12a71d819bb8f50c28938db0f2867d3fb6e2ce5910Douglas Gregornamespace N {
13a71d819bb8f50c28938db0f2867d3fb6e2ce5910Douglas Gregor  typedef Foo Wibble;
1477549080fb7b9af31606b3c1b4830a94429fb1fdDouglas Gregor  typedef int OtherInteger;
15a71d819bb8f50c28938db0f2867d3fb6e2ce5910Douglas Gregor}
16a71d819bb8f50c28938db0f2867d3fb6e2ce5910Douglas Gregor
1781e317a444dd756a1cafe94031e4b3f3c138dac6John McCalltemplate <typename T>
1881e317a444dd756a1cafe94031e4b3f3c138dac6John McCallvoid cv_test(const volatile T* cvt) {
1981e317a444dd756a1cafe94031e4b3f3c138dac6John McCall  cvt->T::~T(); // no-warning
2081e317a444dd756a1cafe94031e4b3f3c138dac6John McCall}
2181e317a444dd756a1cafe94031e4b3f3c138dac6John McCall
2291ec7894ec186dd36f509682f00486c98d8228edDavid Blaikievoid f(A* a, Foo *f, int *i, double *d, int ii) {
232cf738f1944d1cc724ea7561b84440a3a1059e45Anders Carlsson  a->~A();
242cf738f1944d1cc724ea7561b84440a3a1059e45Anders Carlsson  a->A::~A();
252cf738f1944d1cc724ea7561b84440a3a1059e45Anders Carlsson
267ec1873d694cf870264694d2b61219a03492bc30Douglas Gregor  a->~foo(); // expected-error{{identifier 'foo' in object destruction expression does not name a type}}
27a71d819bb8f50c28938db0f2867d3fb6e2ce5910Douglas Gregor
287ec1873d694cf870264694d2b61219a03492bc30Douglas Gregor  a->~Bar(); // expected-error{{destructor type 'Bar' (aka 'Foo') in object destruction expression does not match the type 'A' of the object being destroyed}}
29a71d819bb8f50c28938db0f2867d3fb6e2ce5910Douglas Gregor
30a71d819bb8f50c28938db0f2867d3fb6e2ce5910Douglas Gregor  f->~Bar();
31a71d819bb8f50c28938db0f2867d3fb6e2ce5910Douglas Gregor  f->~Foo();
32a71d819bb8f50c28938db0f2867d3fb6e2ce5910Douglas Gregor  i->~Bar(); // expected-error{{does not match}}
33a71d819bb8f50c28938db0f2867d3fb6e2ce5910Douglas Gregor
34a71d819bb8f50c28938db0f2867d3fb6e2ce5910Douglas Gregor  g().~Bar(); // expected-error{{non-scalar}}
35a71d819bb8f50c28938db0f2867d3fb6e2ce5910Douglas Gregor
36a71d819bb8f50c28938db0f2867d3fb6e2ce5910Douglas Gregor  f->::~Bar();
3793649fdc5e0c46e26bcba06ad39aa80196d3df27Douglas Gregor  f->N::~Wibble(); // FIXME: technically, Wibble isn't a class-name
38a71d819bb8f50c28938db0f2867d3fb6e2ce5910Douglas Gregor
39a71d819bb8f50c28938db0f2867d3fb6e2ce5910Douglas Gregor  f->::~Bar(17, 42); // expected-error{{cannot have any arguments}}
40b10cd04880672103660e5844e51ee91af7361a20Douglas Gregor
41b10cd04880672103660e5844e51ee91af7361a20Douglas Gregor  i->~Integer();
42b10cd04880672103660e5844e51ee91af7361a20Douglas Gregor  i->Integer::~Integer();
4377549080fb7b9af31606b3c1b4830a94429fb1fdDouglas Gregor  i->N::~OtherInteger();
4477549080fb7b9af31606b3c1b4830a94429fb1fdDouglas Gregor  i->N::OtherInteger::~OtherInteger();
4577549080fb7b9af31606b3c1b4830a94429fb1fdDouglas Gregor  i->N::OtherInteger::~Integer(); // expected-error{{'Integer' does not refer to a type name in pseudo-destructor expression; expected the name of type 'int'}}
4677549080fb7b9af31606b3c1b4830a94429fb1fdDouglas Gregor  i->N::~Integer(); // expected-error{{'Integer' does not refer to a type name in pseudo-destructor expression; expected the name of type 'int'}}
4777549080fb7b9af31606b3c1b4830a94429fb1fdDouglas Gregor  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}}
4881e317a444dd756a1cafe94031e4b3f3c138dac6John McCall
4991ec7894ec186dd36f509682f00486c98d8228edDavid Blaikie  ii->~Integer(); // expected-error{{member reference type 'int' is not a pointer; maybe you meant to use '.'?}}
5091ec7894ec186dd36f509682f00486c98d8228edDavid Blaikie  ii.~Integer();
5191ec7894ec186dd36f509682f00486c98d8228edDavid Blaikie
5281e317a444dd756a1cafe94031e4b3f3c138dac6John McCall  cv_test(a);
5381e317a444dd756a1cafe94031e4b3f3c138dac6John McCall  cv_test(f);
5481e317a444dd756a1cafe94031e4b3f3c138dac6John McCall  cv_test(i);
5581e317a444dd756a1cafe94031e4b3f3c138dac6John McCall  cv_test(d);
562cf738f1944d1cc724ea7561b84440a3a1059e45Anders Carlsson}
57a78c5c34fbd20fde02261c3f3e21933cd58fcc04Douglas Gregor
5881e317a444dd756a1cafe94031e4b3f3c138dac6John McCall
59a78c5c34fbd20fde02261c3f3e21933cd58fcc04Douglas Gregortypedef int Integer;
60a78c5c34fbd20fde02261c3f3e21933cd58fcc04Douglas Gregor
61a78c5c34fbd20fde02261c3f3e21933cd58fcc04Douglas Gregorvoid destroy_without_call(int *ip) {
62a78c5c34fbd20fde02261c3f3e21933cd58fcc04Douglas Gregor  ip->~Integer; // expected-error{{called immediately}}
634fcfde4d5c8f25e40720972a5543d538a0dcb220Daniel Dunbar}
64f6e6fc801c700c7b8ac202ddbe550d9843a816fcDouglas Gregor
65f6e6fc801c700c7b8ac202ddbe550d9843a816fcDouglas Gregor// PR5530
66f6e6fc801c700c7b8ac202ddbe550d9843a816fcDouglas Gregornamespace N1 {
67f6e6fc801c700c7b8ac202ddbe550d9843a816fcDouglas Gregor  class X0 { };
68f6e6fc801c700c7b8ac202ddbe550d9843a816fcDouglas Gregor}
69f6e6fc801c700c7b8ac202ddbe550d9843a816fcDouglas Gregor
70f6e6fc801c700c7b8ac202ddbe550d9843a816fcDouglas Gregorvoid test_X0(N1::X0 &x0) {
71f6e6fc801c700c7b8ac202ddbe550d9843a816fcDouglas Gregor  x0.~X0();
72f6e6fc801c700c7b8ac202ddbe550d9843a816fcDouglas Gregor}
7381e317a444dd756a1cafe94031e4b3f3c138dac6John McCall
746b18e740495b67b439fa366367242110365cc4d9Douglas Gregornamespace PR11339 {
756b18e740495b67b439fa366367242110365cc4d9Douglas Gregor  template<class T>
766b18e740495b67b439fa366367242110365cc4d9Douglas Gregor  void destroy(T* p) {
776b18e740495b67b439fa366367242110365cc4d9Douglas Gregor    p->~T(); // ok
786b18e740495b67b439fa366367242110365cc4d9Douglas Gregor    p->~oops(); // expected-error{{expected the class name after '~' to name a destructor}}
796b18e740495b67b439fa366367242110365cc4d9Douglas Gregor  }
806b18e740495b67b439fa366367242110365cc4d9Douglas Gregor
816b18e740495b67b439fa366367242110365cc4d9Douglas Gregor  template void destroy(int*); // expected-note{{in instantiation of function template specialization}}
826b18e740495b67b439fa366367242110365cc4d9Douglas Gregor}
83d6537015745128064dc12fcc06af65372dfd5da9Richard Smith
84d6537015745128064dc12fcc06af65372dfd5da9Richard Smithtemplate<typename T> using Id = T;
85d6537015745128064dc12fcc06af65372dfd5da9Richard Smithvoid AliasTemplate(int *p) {
86d6537015745128064dc12fcc06af65372dfd5da9Richard Smith  p->~Id<int>();
87d6537015745128064dc12fcc06af65372dfd5da9Richard Smith}
88