2009-12-16 04:14:24 +08:00
// RUN: %clang_cc1 -fsyntax-only -verify %s
2008-11-25 12:08:05 +08:00
2008-12-04 04:26:15 +08:00
# include <stddef.h>
2008-11-22 03:14:01 +08:00
struct S // expected-note {{candidate}}
{
S ( int , int , double ) ; // expected-note {{candidate}}
2009-02-08 03:52:04 +08:00
S ( double , int ) ; // expected-note 2 {{candidate}}
S ( float , int ) ; // expected-note 2 {{candidate}}
2008-11-22 03:14:01 +08:00
} ;
2010-03-10 19:27:22 +08:00
struct T ; // expected-note{{forward declaration of 'T'}}
2008-12-05 01:24:46 +08:00
struct U
{
// A special new, to verify that the global version isn't used.
2009-05-15 02:11:41 +08:00
void * operator new ( size_t , S * ) ; // expected-note {{candidate}}
2008-12-05 01:24:46 +08:00
} ;
2008-12-05 06:20:51 +08:00
struct V : U
{
} ;
2008-11-22 03:14:01 +08:00
2009-12-23 07:42:49 +08:00
// PR5823
void * operator new ( const size_t ) ; // expected-note 2 {{candidate}}
2009-02-08 03:52:04 +08:00
void * operator new ( size_t , int * ) ; // expected-note 3 {{candidate}}
void * operator new ( size_t , float * ) ; // expected-note 3 {{candidate}}
2009-06-01 03:49:47 +08:00
void * operator new ( size_t , S ) ; // expected-note 2 {{candidate}}
2008-12-04 04:26:15 +08:00
2010-05-17 00:01:03 +08:00
struct foo { } ;
2008-11-22 03:14:01 +08:00
void good_news ( )
{
int * pi = new int ;
float * pf = new ( pi ) float ( ) ;
pi = new int ( 1 ) ;
pi = new int ( ' c ' ) ;
const int * pci = new const int ( ) ;
S * ps = new S ( 1 , 2 , 3.4 ) ;
2008-12-02 22:43:59 +08:00
ps = new ( pf ) ( S ) ( 1 , 2 , 3.4 ) ;
2008-11-22 03:14:01 +08:00
S * ( * paps ) [ 2 ] = new S * [ * pi ] [ 2 ] ;
typedef int ia4 [ 4 ] ;
ia4 * pai = new ( int [ 3 ] [ 4 ] ) ;
2008-12-03 00:35:44 +08:00
pi = : : new int ;
2008-12-05 01:24:46 +08:00
U * pu = new ( ps ) U ;
2009-09-30 08:03:47 +08:00
V * pv = new ( ps ) V ;
2009-06-01 03:49:47 +08:00
pi = new ( S ( 1.0f , 2 ) ) int ;
2009-09-23 08:37:25 +08:00
( void ) new int [ true ] ;
2010-05-17 00:01:03 +08:00
// PR7147
typedef int a [ 2 ] ;
foo * f1 = new foo ;
foo * f2 = new foo [ 2 ] ;
typedef foo x [ 2 ] ;
typedef foo y [ 2 ] [ 2 ] ;
x * f3 = new y ;
2008-11-22 03:14:01 +08:00
}
2009-03-25 03:52:54 +08:00
struct abstract {
virtual ~ abstract ( ) = 0 ;
} ;
2008-11-25 12:08:05 +08:00
void bad_news ( int * ip )
2008-11-22 03:14:01 +08:00
{
int i = 1 ;
2010-11-04 01:52:57 +08:00
( void ) new ; // expected-error {{expected a type}}
( void ) new 4 ; // expected-error {{expected a type}}
2008-11-22 03:14:01 +08:00
( void ) new ( ) int ; // expected-error {{expected expression}}
2008-12-02 22:43:59 +08:00
( void ) new int [ 1.1 ] ; // expected-error {{array size expression must have integral or enumerated type, not 'double'}}
2008-11-22 03:14:01 +08:00
( void ) new int [ 1 ] [ i ] ; // expected-error {{only the first dimension}}
( void ) new ( int [ 1 ] [ i ] ) ; // expected-error {{only the first dimension}}
2010-07-13 23:54:32 +08:00
( void ) new ( int [ i ] ) ; // expected-warning {{when type is in parentheses}}
2010-03-10 19:27:22 +08:00
( void ) new int ( * ( S * ) 0 ) ; // expected-error {{no viable conversion from 'S' to 'int'}}
2009-12-16 09:38:02 +08:00
( void ) new int ( 1 , 2 ) ; // expected-error {{excess elements in scalar initializer}}
2008-11-22 03:14:01 +08:00
( void ) new S ( 1 ) ; // expected-error {{no matching constructor}}
2010-03-10 19:27:22 +08:00
( void ) new S ( 1 , 1 ) ; // expected-error {{call to constructor of 'S' is ambiguous}}
2010-09-05 08:04:01 +08:00
( void ) new const int ; // expected-error {{default initialization of an object of const type 'const int'}}
2010-01-23 13:47:27 +08:00
( void ) new float * ( ip ) ; // expected-error {{cannot initialize a new value of type 'float *' with an lvalue of type 'int *'}}
2008-12-02 22:43:59 +08:00
// Undefined, but clang should reject it directly.
( void ) new int [ - 1 ] ; // expected-error {{array size is negative}}
2010-03-10 19:27:22 +08:00
( void ) new int [ * ( S * ) 0 ] ; // expected-error {{array size expression must have integral or enumerated type, not 'S'}}
2008-12-03 00:35:44 +08:00
( void ) : : S : : new int ; // expected-error {{expected unqualified-id}}
2008-12-04 04:26:15 +08:00
( void ) new ( 0 , 0 ) int ; // expected-error {{no matching function for call to 'operator new'}}
2008-12-05 06:20:51 +08:00
( void ) new ( 0L ) int ; // expected-error {{call to 'operator new' is ambiguous}}
2008-12-05 01:24:46 +08:00
// This must fail, because the member version shouldn't be found.
( void ) : : new ( ( S * ) 0 ) U ; // expected-error {{no matching function for call to 'operator new'}}
2009-05-15 02:11:41 +08:00
// This must fail, because any member version hides all global versions.
( void ) new U ; // expected-error {{no matching function for call to 'operator new'}}
2009-02-10 02:24:27 +08:00
( void ) new ( int [ ] ) ; // expected-error {{array size must be specified in new expressions}}
( void ) new int & ; // expected-error {{cannot allocate reference type 'int &' with new}}
2008-11-22 03:14:01 +08:00
// Some lacking cases due to lack of sema support.
}
void good_deletes ( )
{
delete ( int * ) 0 ;
delete [ ] ( int * ) 0 ;
delete ( S * ) 0 ;
2008-12-03 00:35:44 +08:00
: : delete ( int * ) 0 ;
2008-11-22 03:14:01 +08:00
}
void bad_deletes ( )
{
delete 0 ; // expected-error {{cannot delete expression of type 'int'}}
delete [ 0 ] ( int * ) 0 ; / / expected - error { { expected ' ] ' } } \
2008-11-24 07:17:07 +08:00
// expected-note {{to match this '['}}
2010-05-25 01:01:56 +08:00
delete ( void * ) 0 ; // expected-warning {{cannot delete expression with pointer-to-'void' type 'void *'}}
2008-11-22 03:14:01 +08:00
delete ( T * ) 0 ; // expected-warning {{deleting pointer to incomplete type}}
2008-12-03 00:35:44 +08:00
: : S : : delete ( int * ) 0 ; // expected-error {{expected unqualified-id}}
2008-11-22 03:14:01 +08:00
}
2009-09-10 07:39:55 +08:00
struct X0 { } ;
struct X1 {
operator int * ( ) ;
operator float ( ) ;
} ;
struct X2 {
2009-09-16 01:21:47 +08:00
operator int * ( ) ; // expected-note {{candidate function}}
operator float * ( ) ; // expected-note {{candidate function}}
2009-09-10 07:39:55 +08:00
} ;
void test_delete_conv ( X0 x0 , X1 x1 , X2 x2 ) {
delete x0 ; // expected-error{{cannot delete}}
delete x1 ;
2010-03-10 19:27:22 +08:00
delete x2 ; // expected-error{{ambiguous conversion of delete expression of type 'X2' to a pointer}}
2009-09-16 01:21:47 +08:00
}
2009-09-30 02:16:17 +08:00
// PR4782
class X3 {
public :
2009-11-16 13:14:40 +08:00
static void operator delete ( void * mem , size_t size ) ;
2009-09-30 02:16:17 +08:00
} ;
class X4 {
public :
static void release ( X3 * x ) ;
2009-11-16 13:14:40 +08:00
static void operator delete ( void * mem , size_t size ) ;
2009-09-30 02:16:17 +08:00
} ;
void X4 : : release ( X3 * x ) {
delete x ;
}
2009-09-30 05:38:53 +08:00
2009-09-30 08:03:47 +08:00
class X5 {
2009-09-30 05:38:53 +08:00
public :
void Destroy ( ) const { delete this ; }
} ;
2009-11-11 07:47:18 +08:00
class Base {
public :
2009-12-14 01:53:43 +08:00
static void * operator new ( signed char ) throw ( ) ; // expected-error {{'operator new' takes type size_t}}
static int operator new [ ] ( size_t ) throw ( ) ; // expected-error {{operator new[]' must return type 'void *'}}
2009-11-11 07:47:18 +08:00
} ;
class Tier { } ;
class Comp : public Tier { } ;
class Thai : public Base {
public :
Thai ( const Tier * adoptDictionary ) ;
} ;
void loadEngineFor ( ) {
const Comp * dict ;
new Thai ( dict ) ;
}
template < class T > struct TBase {
2010-02-17 03:28:15 +08:00
void * operator new ( T size , int ) ; // expected-error {{'operator new' cannot take a dependent type as first parameter; use size_t}}
2009-11-11 07:47:18 +08:00
} ;
2010-02-17 03:28:15 +08:00
TBase < int > t1 ;
2009-11-11 07:47:18 +08:00
2009-11-14 11:17:38 +08:00
class X6 {
public :
static void operator delete ( void * , int ) ; // expected-note {{member found by ambiguous name lookup}}
} ;
class X7 {
public :
static void operator delete ( void * , int ) ; // expected-note {{member found by ambiguous name lookup}}
} ;
class X8 : public X6 , public X7 {
} ;
2009-11-16 00:43:15 +08:00
void f ( X8 * x8 ) {
2009-11-14 11:17:38 +08:00
delete x8 ; // expected-error {{member 'operator delete' found in multiple base classes of different types}}
}
2009-11-16 00:43:15 +08:00
class X9 {
2010-04-10 03:03:51 +08:00
public :
2009-11-16 00:43:15 +08:00
static void operator delete ( void * , int ) ; // expected-note {{'operator delete' declared here}}
static void operator delete ( void * , float ) ; // expected-note {{'operator delete' declared here}}
} ;
void f ( X9 * x9 ) {
delete x9 ; // expected-error {{no suitable member 'operator delete' in 'X9'}}
}
2009-12-01 05:24:50 +08:00
struct X10 {
virtual ~ X10 ( ) ;
} ;
struct X11 : X10 { // expected-error {{no suitable member 'operator delete' in 'X11'}}
void operator delete ( void * , int ) ; // expected-note {{'operator delete' declared here}}
} ;
void f ( ) {
2010-03-10 19:27:22 +08:00
X11 x11 ; // expected-note {{implicit default destructor for 'X11' first required here}}
2009-12-01 05:24:50 +08:00
}
2009-12-09 15:39:44 +08:00
struct X12 {
void * operator new ( size_t , void * ) ;
} ;
struct X13 : X12 {
using X12 : : operator new ;
} ;
static void * f ( void * g )
{
return new ( g ) X13 ( ) ;
}
2010-02-03 19:02:14 +08:00
2010-02-09 02:54:05 +08:00
class X14 {
2010-04-10 03:03:51 +08:00
public :
2010-02-09 02:54:05 +08:00
static void operator delete ( void * , const size_t ) ;
} ;
void f ( X14 * x14a , X14 * x14b ) {
delete x14a ;
}
2011-02-01 23:50:11 +08:00
class X15 {
private :
X15 ( ) ; // expected-note {{declared private here}}
~ X15 ( ) ; // expected-note {{declared private here}}
} ;
void f ( X15 * x ) {
new X15 ( ) ; // expected-error {{calling a private constructor}}
delete x ; // expected-error {{calling a private destructor}}
}
2010-02-03 19:02:14 +08:00
namespace PR5918 { // Look for template operator new overloads.
struct S { template < typename T > static void * operator new ( size_t , T ) ; } ;
void test ( ) {
( void ) new ( 0 ) S ;
}
}
2010-05-03 23:45:23 +08:00
namespace Test1 {
void f ( ) {
( void ) new int [ 10 ] ( 1 , 2 ) ; // expected-error {{array 'new' cannot have initialization arguments}}
2010-05-17 00:24:20 +08:00
typedef int T [ 10 ] ;
( void ) new T ( 1 , 2 ) ; // expected-error {{array 'new' cannot have initialization arguments}}
2010-05-03 23:45:23 +08:00
}
template < typename T >
void g ( unsigned i ) {
( void ) new T [ 1 ] ( i ) ; // expected-error {{array 'new' cannot have initialization arguments}}
}
template < typename T >
void h ( unsigned i ) {
( void ) new T ( i ) ; // expected-error {{array 'new' cannot have initialization arguments}}
}
template void h < unsigned > ( unsigned ) ;
template void h < unsigned [ 10 ] > ( unsigned ) ; // expected-note {{in instantiation of function template specialization 'Test1::h<unsigned int [10]>' requested here}}
}
2010-06-28 08:30:51 +08:00
// Don't diagnose access for overload candidates that aren't selected.
namespace PR7436 {
struct S1 {
void * operator new ( size_t ) ;
void operator delete ( void * p ) ;
private :
void * operator new ( size_t , void * ) ; // expected-note {{declared private here}}
void operator delete ( void * , void * ) ;
} ;
class S2 {
void * operator new ( size_t ) ; // expected-note {{declared private here}}
void operator delete ( void * p ) ; // expected-note {{declared private here}}
} ;
void test ( S1 * s1 , S2 * s2 ) {
delete s1 ;
delete s2 ; // expected-error {{is a private member}}
( void ) new S1 ( ) ;
( void ) new ( 0L ) S1 ( ) ; // expected-error {{is a private member}}
( void ) new S2 ( ) ; // expected-error {{is a private member}}
}
}
2010-06-30 08:20:43 +08:00
2010-07-13 23:54:32 +08:00
namespace rdar8018245 {
struct X0 {
static const int value = 17 ;
} ;
const int X0 : : value ;
struct X1 {
static int value ;
} ;
int X1 : : value ;
template < typename T >
int * f ( ) {
return new ( int [ T : : value ] ) ; // expected-warning{{when type is in parentheses, array cannot have dynamic size}}
}
template int * f < X0 > ( ) ;
template int * f < X1 > ( ) ; // expected-note{{in instantiation of}}
}
2010-07-29 22:44:35 +08:00
// <rdar://problem/8248780>
namespace Instantiate {
template < typename T > struct X {
operator T * ( ) ;
} ;
void f ( X < int > & xi ) {
delete xi ;
}
}
2010-08-05 08:45:34 +08:00
namespace PR7810 {
struct X {
// cv is ignored in arguments
static void operator delete ( void * const ) ;
} ;
struct Y {
// cv is ignored in arguments
static void operator delete ( void * volatile ) ;
} ;
}
2010-08-08 15:04:00 +08:00
// Don't crash on template delete operators
namespace TemplateDestructors {
struct S {
virtual ~ S ( ) { }
void * operator new ( const size_t size ) ;
template < class T > void * operator new ( const size_t , const int , T * ) ;
void operator delete ( void * , const size_t ) ;
template < class T > void operator delete ( void * , const size_t , const int , T * ) ;
} ;
}
2010-08-28 05:39:15 +08:00
namespace DeleteParam {
struct X {
void operator delete ( X * ) ; // expected-error{{first parameter of 'operator delete' must have type 'void *'}}
} ;
struct Y {
void operator delete ( void * const ) ;
} ;
}
2010-09-15 05:34:24 +08:00
// <rdar://problem/8427878>
// Test that the correct 'operator delete' is selected to pair with
// the unexpected placement 'operator new'.
namespace PairedDelete {
template < class T > struct A {
A ( ) ;
void * operator new ( size_t s , double d = 0 ) ;
void operator delete ( void * p , double d ) ;
void operator delete ( void * p ) {
T : : dealloc ( p ) ;
}
} ;
A < int > * test ( ) {
return new A < int > ( ) ;
}
}
2010-11-04 01:52:57 +08:00
namespace PR7702 {
void test1 ( ) {
new DoesNotExist ; // expected-error {{expected a type}}
}
}
2011-07-14 04:12:57 +08:00
namespace ArrayNewNeedsDtor {
struct A { A ( ) ; private : ~ A ( ) ; } ; // expected-note {{declared private here}}
struct B { B ( ) ; A a ; } ; // expected-error {{field of type 'ArrayNewNeedsDtor::A' has private destructor}}
B * test9 ( ) {
return new B [ 5 ] ; // expected-note {{implicit default destructor for 'ArrayNewNeedsDtor::B' first required here}}
}
}
2011-07-27 06:25:31 +08:00
namespace DeleteIncompleteClass {
struct A ; // expected-note {{forward declaration}}
extern A x ;
void f ( ) { delete x ; } // expected-error {{deleting incomplete class type}}
}
namespace DeleteIncompleteClassPointerError {
struct A ; // expected-note {{forward declaration}}
void f ( A * x ) { 1 + delete x ; } / / expected - warning { { deleting pointer to incomplete type } } \
// expected-error {{invalid operands to binary expression}}
}
2011-07-27 06:50:18 +08:00
namespace PR10504 {
struct A {
virtual void foo ( ) = 0 ;
} ;
void f ( A * x ) { delete x ; } // expected-error {{cannot delete 'PR10504::A', which is abstract and does not have a virtual destructor}}
}