142 lines
3.1 KiB
C++
142 lines
3.1 KiB
C++
|
// RUN: %clang_cc1 -fsyntax-only -verify -fexceptions %s
|
||
|
typedef __SIZE_TYPE__ size_t;
|
||
|
|
||
|
// Overloaded operator delete with two arguments
|
||
|
template<int I>
|
||
|
struct X0 {
|
||
|
X0();
|
||
|
static void* operator new(size_t);
|
||
|
static void operator delete(void*, size_t) {
|
||
|
int *ip = I; // expected-error{{cannot initialize}}
|
||
|
}
|
||
|
};
|
||
|
|
||
|
void test_X0() {
|
||
|
new X0<1>; // expected-note{{instantiation}}
|
||
|
}
|
||
|
|
||
|
// Overloaded operator delete with one argument
|
||
|
template<int I>
|
||
|
struct X1 {
|
||
|
X1();
|
||
|
|
||
|
static void* operator new(size_t);
|
||
|
static void operator delete(void*) {
|
||
|
int *ip = I; // expected-error{{cannot initialize}}
|
||
|
}
|
||
|
};
|
||
|
|
||
|
void test_X1() {
|
||
|
new X1<1>; // expected-note{{instantiation}}
|
||
|
}
|
||
|
|
||
|
// Overloaded operator delete for placement new
|
||
|
template<int I>
|
||
|
struct X2 {
|
||
|
X2();
|
||
|
|
||
|
static void* operator new(size_t, double, double);
|
||
|
static void* operator new(size_t, int, int);
|
||
|
|
||
|
static void operator delete(void*, const int, int) {
|
||
|
int *ip = I; // expected-error{{cannot initialize}}
|
||
|
}
|
||
|
|
||
|
static void operator delete(void*, double, double);
|
||
|
};
|
||
|
|
||
|
void test_X2() {
|
||
|
new (0, 0) X2<1>; // expected-note{{instantiation}}
|
||
|
}
|
||
|
|
||
|
// Operator delete template for placement new
|
||
|
struct X3 {
|
||
|
X3();
|
||
|
|
||
|
static void* operator new(size_t, double, double);
|
||
|
|
||
|
template<typename T>
|
||
|
static void operator delete(void*, T x, T) {
|
||
|
double *dp = &x;
|
||
|
int *ip = &x; // expected-error{{cannot initialize}}
|
||
|
}
|
||
|
};
|
||
|
|
||
|
void test_X3() {
|
||
|
new (0, 0) X3; // expected-note{{instantiation}}
|
||
|
}
|
||
|
|
||
|
// Operator delete template for placement new in global scope.
|
||
|
struct X4 {
|
||
|
X4();
|
||
|
static void* operator new(size_t, double, double);
|
||
|
};
|
||
|
|
||
|
template<typename T>
|
||
|
void operator delete(void*, T x, T) {
|
||
|
double *dp = &x;
|
||
|
int *ip = &x; // expected-error{{cannot initialize}}
|
||
|
}
|
||
|
|
||
|
void test_X4() {
|
||
|
new (0, 0) X4; // expected-note{{instantiation}}
|
||
|
}
|
||
|
|
||
|
// Useless operator delete hides global operator delete template.
|
||
|
struct X5 {
|
||
|
X5();
|
||
|
static void* operator new(size_t, double, double);
|
||
|
void operator delete(void*, double*, double*);
|
||
|
};
|
||
|
|
||
|
void test_X5() {
|
||
|
new (0, 0) X5; // okay, we found X5::operator delete but didn't pick it
|
||
|
}
|
||
|
|
||
|
// Operator delete template for placement new
|
||
|
template<int I>
|
||
|
struct X6 {
|
||
|
X6();
|
||
|
|
||
|
static void* operator new(size_t) {
|
||
|
return I; // expected-error{{cannot initialize}}
|
||
|
}
|
||
|
|
||
|
static void operator delete(void*) {
|
||
|
int *ip = I; // expected-error{{cannot initialize}}
|
||
|
}
|
||
|
};
|
||
|
|
||
|
void test_X6() {
|
||
|
new X6<3>; // expected-note 2{{instantiation}}
|
||
|
}
|
||
|
|
||
|
void *operator new(size_t, double, double, double);
|
||
|
|
||
|
template<typename T>
|
||
|
void operator delete(void*, T x, T, T) {
|
||
|
double *dp = &x;
|
||
|
int *ip = &x; // expected-error{{cannot initialize}}
|
||
|
}
|
||
|
void test_int_new() {
|
||
|
new (1.0, 1.0, 1.0) int; // expected-note{{instantiation}}
|
||
|
}
|
||
|
|
||
|
// We don't need an operator delete if the type has a trivial
|
||
|
// constructor, since we know that constructor cannot throw.
|
||
|
// FIXME: Is this within the standard? Seems fishy, but both EDG+GCC do it.
|
||
|
#if 0
|
||
|
template<int I>
|
||
|
struct X7 {
|
||
|
static void* operator new(size_t);
|
||
|
static void operator delete(void*, size_t) {
|
||
|
int *ip = I; // okay, since it isn't instantiated.
|
||
|
}
|
||
|
};
|
||
|
|
||
|
void test_X7() {
|
||
|
new X7<1>;
|
||
|
}
|
||
|
#endif
|
||
|
|