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
|