2012-11-15 08:31:27 +08:00
// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
2009-08-27 03:22:42 +08:00
struct A { } ;
enum Foo { F } ;
2011-03-05 06:32:08 +08:00
typedef Foo Bar ; // expected-note{{type 'Bar' (aka 'Foo') is declared here}}
2009-08-27 03:22:42 +08:00
2009-09-05 01:36:40 +08:00
typedef int Integer ;
2010-02-22 02:36:56 +08:00
typedef double Double ;
2009-09-05 01:36:40 +08:00
void g ( ) ;
namespace N {
typedef Foo Wibble ;
2010-02-25 05:29:12 +08:00
typedef int OtherInteger ;
2009-09-05 01:36:40 +08:00
}
2010-06-12 01:36:40 +08:00
template < typename T >
void cv_test ( const volatile T * cvt ) {
cvt - > T : : ~ T ( ) ; // no-warning
}
2011-12-17 00:03:09 +08:00
void f ( A * a , Foo * f , int * i , double * d , int ii ) {
2009-08-27 03:22:42 +08:00
a - > ~ A ( ) ;
a - > A : : ~ A ( ) ;
2011-03-05 06:32:08 +08:00
a - > ~ foo ( ) ; // expected-error{{identifier 'foo' in object destruction expression does not name a type}}
2009-09-05 01:36:40 +08:00
2011-03-05 06:32:08 +08:00
a - > ~ Bar ( ) ; // expected-error{{destructor type 'Bar' (aka 'Foo') in object destruction expression does not match the type 'A' of the object being destroyed}}
2009-09-05 01:36:40 +08:00
f - > ~ Bar ( ) ;
f - > ~ Foo ( ) ;
i - > ~ Bar ( ) ; // expected-error{{does not match}}
g ( ) . ~ Bar ( ) ; // expected-error{{non-scalar}}
f - > : : ~ Bar ( ) ;
2010-02-23 08:15:22 +08:00
f - > N : : ~ Wibble ( ) ; // FIXME: technically, Wibble isn't a class-name
2009-09-05 01:36:40 +08:00
f - > : : ~ Bar ( 17 , 42 ) ; // expected-error{{cannot have any arguments}}
2010-02-22 02:36:56 +08:00
i - > ~ Integer ( ) ;
i - > Integer : : ~ Integer ( ) ;
2010-02-25 05:29:12 +08:00
i - > N : : ~ OtherInteger ( ) ;
i - > N : : OtherInteger : : ~ OtherInteger ( ) ;
i - > N : : OtherInteger : : ~ Integer ( ) ; // expected-error{{'Integer' does not refer to a type name in pseudo-destructor expression; expected the name of type 'int'}}
i - > N : : ~ Integer ( ) ; // expected-error{{'Integer' does not refer to a type name in pseudo-destructor expression; expected the name of type 'int'}}
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}}
2010-06-12 01:36:40 +08:00
2011-12-17 00:03:09 +08:00
ii - > ~ Integer ( ) ; // expected-error{{member reference type 'int' is not a pointer; maybe you meant to use '.'?}}
ii . ~ Integer ( ) ;
2010-06-12 01:36:40 +08:00
cv_test ( a ) ;
cv_test ( f ) ;
cv_test ( i ) ;
cv_test ( d ) ;
2009-08-27 03:22:42 +08:00
}
2009-09-05 02:29:40 +08:00
2010-06-12 01:36:40 +08:00
2009-09-05 02:29:40 +08:00
typedef int Integer ;
void destroy_without_call ( int * ip ) {
ip - > ~ Integer ; // expected-error{{called immediately}}
2009-11-08 09:45:36 +08:00
}
2009-11-21 06:03:38 +08:00
// PR5530
namespace N1 {
class X0 { } ;
}
void test_X0 ( N1 : : X0 & x0 ) {
x0 . ~ X0 ( ) ;
}
2010-06-12 01:36:40 +08:00
2011-11-09 10:19:47 +08:00
namespace PR11339 {
template < class T >
void destroy ( T * p ) {
p - > ~ T ( ) ; // ok
p - > ~ oops ( ) ; // expected-error{{expected the class name after '~' to name a destructor}}
}
template void destroy ( int * ) ; // expected-note{{in instantiation of function template specialization}}
}
2012-11-15 08:31:27 +08:00
template < typename T > using Id = T ;
void AliasTemplate ( int * p ) {
p - > ~ Id < int > ( ) ;
}