1// RUN: %clang_cc1 -fsyntax-only -verify -fexceptions %s
2typedef __SIZE_TYPE__ size_t;
3
4// Overloaded operator delete with two arguments
5template<int I>
6struct X0 {
7  X0();
8  static void* operator new(size_t);
9  static void operator delete(void*, size_t) {
10    int *ip = I; // expected-error{{cannot initialize}}
11  }
12};
13
14void test_X0() {
15  new X0<1>; // expected-note{{instantiation}}
16}
17
18// Overloaded operator delete with one argument
19template<int I>
20struct X1 {
21  X1();
22
23  static void* operator new(size_t);
24  static void operator delete(void*) {
25    int *ip = I; // expected-error{{cannot initialize}}
26  }
27};
28
29void test_X1() {
30  new X1<1>; // expected-note{{instantiation}}
31}
32
33// Overloaded operator delete for placement new
34template<int I>
35struct X2 {
36  X2();
37
38  static void* operator new(size_t, double, double);
39  static void* operator new(size_t, int, int);
40
41  static void operator delete(void*, const int, int) {
42    int *ip = I; // expected-error{{cannot initialize}}
43  }
44
45  static void operator delete(void*, double, double);
46};
47
48void test_X2() {
49  new (0, 0) X2<1>; // expected-note{{instantiation}}
50}
51
52// Operator delete template for placement new
53struct X3 {
54  X3();
55
56  static void* operator new(size_t, double, double);
57
58  template<typename T>
59  static void operator delete(void*, T x, T) {
60    double *dp = &x;
61    int *ip = &x; // expected-error{{cannot initialize}}
62  }
63};
64
65void test_X3() {
66  new (0, 0) X3; // expected-note{{instantiation}}
67}
68
69// Operator delete template for placement new in global scope.
70struct X4 {
71  X4();
72  static void* operator new(size_t, double, double);
73};
74
75template<typename T>
76void operator delete(void*, T x, T) {
77  double *dp = &x;
78  int *ip = &x; // expected-error{{cannot initialize}}
79}
80
81void test_X4() {
82  new (0, 0) X4; // expected-note{{instantiation}}
83}
84
85// Useless operator delete hides global operator delete template.
86struct X5 {
87  X5();
88  static void* operator new(size_t, double, double);
89  void operator delete(void*, double*, double*);
90};
91
92void test_X5() {
93  new (0, 0) X5; // okay, we found X5::operator delete but didn't pick it
94}
95
96// Operator delete template for placement new
97template<int I>
98struct X6 {
99  X6();
100
101  static void* operator new(size_t) {
102    return I; // expected-error{{cannot initialize}}
103  }
104
105  static void operator delete(void*) {
106    int *ip = I; // expected-error{{cannot initialize}}
107  }
108};
109
110void test_X6() {
111  new X6<3>; // expected-note 2{{instantiation}}
112}
113
114void *operator new(size_t, double, double, double);
115
116template<typename T>
117void operator delete(void*, T x, T, T) {
118  double *dp = &x;
119  int *ip = &x; // expected-error{{cannot initialize}}
120}
121void test_int_new() {
122  new (1.0, 1.0, 1.0) int; // expected-note{{instantiation}}
123}
124
125// We don't need an operator delete if the type has a trivial
126// constructor, since we know that constructor cannot throw.
127// FIXME: Is this within the standard? Seems fishy, but both EDG+GCC do it.
128#if 0
129template<int I>
130struct X7 {
131  static void* operator new(size_t);
132  static void operator delete(void*, size_t) {
133    int *ip = I; // okay, since it isn't instantiated.
134  }
135};
136
137void test_X7() {
138  new X7<1>;
139}
140#endif
141
142