1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141
|
// 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
|