1 // RUN: %clang_cc1 -fsyntax-only -verify -fexceptions %s
2 typedef __SIZE_TYPE__ size_t;
3 
4 // Overloaded operator delete with two arguments
5 template<int I>
6 struct X0 {
7   X0();
8   static void* operator new(size_t);
operator deleteX09   static void operator delete(void*, size_t) {
10     int *ip = I; // expected-error{{cannot initialize}}
11   }
12 };
13 
test_X0()14 void test_X0() {
15   new X0<1>; // expected-note{{instantiation}}
16 }
17 
18 // Overloaded operator delete with one argument
19 template<int I>
20 struct X1 {
21   X1();
22 
23   static void* operator new(size_t);
operator deleteX124   static void operator delete(void*) {
25     int *ip = I; // expected-error{{cannot initialize}}
26   }
27 };
28 
test_X1()29 void test_X1() {
30   new X1<1>; // expected-note{{instantiation}}
31 }
32 
33 // Overloaded operator delete for placement new
34 template<int I>
35 struct X2 {
36   X2();
37 
38   static void* operator new(size_t, double, double);
39   static void* operator new(size_t, int, int);
40 
operator deleteX241   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 
test_X2()48 void test_X2() {
49   new (0, 0) X2<1>; // expected-note{{instantiation}}
50 }
51 
52 // Operator delete template for placement new
53 struct X3 {
54   X3();
55 
56   static void* operator new(size_t, double, double);
57 
58   template<typename T>
operator deleteX359   static void operator delete(void*, T x, T) {
60     double *dp = &x;
61     int *ip = &x; // expected-error{{cannot initialize}}
62   }
63 };
64 
test_X3()65 void test_X3() {
66   new (0, 0) X3; // expected-note{{instantiation}}
67 }
68 
69 // Operator delete template for placement new in global scope.
70 struct X4 {
71   X4();
72   static void* operator new(size_t, double, double);
73 };
74 
75 template<typename T>
operator delete(void *,T x,T)76 void operator delete(void*, T x, T) {
77   double *dp = &x;
78   int *ip = &x; // expected-error{{cannot initialize}}
79 }
80 
test_X4()81 void test_X4() {
82   new (0, 0) X4; // expected-note{{instantiation}}
83 }
84 
85 // Useless operator delete hides global operator delete template.
86 struct X5 {
87   X5();
88   static void* operator new(size_t, double, double);
89   void operator delete(void*, double*, double*);
90 };
91 
test_X5()92 void 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
97 template<int I>
98 struct X6 {
99   X6();
100 
operator newX6101   static void* operator new(size_t) {
102     return I; // expected-error{{cannot initialize}}
103   }
104 
operator deleteX6105   static void operator delete(void*) {
106     int *ip = I; // expected-error{{cannot initialize}}
107   }
108 };
109 
test_X6()110 void test_X6() {
111   new X6<3>; // expected-note 2{{instantiation}}
112 }
113 
114 void *operator new(size_t, double, double, double);
115 
116 template<typename T>
operator delete(void *,T x,T,T)117 void operator delete(void*, T x, T, T) {
118   double *dp = &x;
119   int *ip = &x; // expected-error{{cannot initialize}}
120 }
test_int_new()121 void 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
129 template<int I>
130 struct 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 
137 void test_X7() {
138   new X7<1>;
139 }
140 #endif
141 
142