xref: /llvm-project/clang/test/SemaTemplate/instantiate-expr-4.cpp (revision 3e1e527826048b8ae3b9f597729fc888664a233c)
1 // RUN: clang-cc -fsyntax-only -verify %s
2 
3 // ---------------------------------------------------------------------
4 // C++ Functional Casts
5 // ---------------------------------------------------------------------
6 template<int N>
7 struct ValueInit0 {
8   int f() {
9     return int();
10   }
11 };
12 
13 template struct ValueInit0<5>;
14 
15 template<int N>
16 struct FunctionalCast0 {
17   int f() {
18     return int(N);
19   }
20 };
21 
22 template struct FunctionalCast0<5>;
23 
24 struct X { // expected-note 2 {{candidate function}}
25   X(int, int); // expected-note 2 {{candidate function}}
26 };
27 
28 template<int N, int M>
29 struct BuildTemporary0 {
30   X f() {
31     return X(N, M);
32   }
33 };
34 
35 template struct BuildTemporary0<5, 7>;
36 
37 template<int N, int M>
38 struct Temporaries0 {
39   void f() {
40     (void)X(N, M);
41   }
42 };
43 
44 template struct Temporaries0<5, 7>;
45 
46 // ---------------------------------------------------------------------
47 // new/delete expressions
48 // ---------------------------------------------------------------------
49 struct Y { };
50 
51 template<typename T>
52 struct New0 {
53   T* f(bool x) {
54     if (x)
55       return new T; // expected-error{{no matching}}
56     else
57       return new T();
58   }
59 };
60 
61 template struct New0<int>;
62 template struct New0<Y>;
63 template struct New0<X>; // expected-note{{instantiation}}
64 
65 template<typename T, typename Arg1>
66 struct New1 {
67   T* f(bool x, Arg1 a1) {
68     return new T(a1); // expected-error{{no matching}}
69   }
70 };
71 
72 template struct New1<int, float>;
73 template struct New1<Y, Y>;
74 template struct New1<X, Y>; // expected-note{{instantiation}}
75 
76 template<typename T, typename Arg1, typename Arg2>
77 struct New2 {
78   T* f(bool x, Arg1 a1, Arg2 a2) {
79     return new T(a1, a2); // expected-error{{no matching}}
80   }
81 };
82 
83 template struct New2<X, int, float>;
84 template struct New2<X, int, int*>; // expected-note{{instantiation}}
85 // FIXME: template struct New2<int, int, float>;
86 
87 template<typename T>
88 struct Delete0 {
89   void f(T t) {
90     delete t; // expected-error{{cannot delete}}
91     ::delete [] t;
92   }
93 };
94 
95 template struct Delete0<int*>;
96 template struct Delete0<X*>;
97 template struct Delete0<int>; // expected-note{{instantiation}}
98 
99 // ---------------------------------------------------------------------
100 // throw expressions
101 // ---------------------------------------------------------------------
102 template<typename T>
103 struct Throw1 {
104   void f(T t) {
105     throw;
106     throw t; // expected-error{{incomplete type}}
107   }
108 };
109 
110 struct Incomplete; // expected-note{{forward}}
111 
112 template struct Throw1<int>;
113 template struct Throw1<int*>;
114 template struct Throw1<Incomplete*>; // expected-note{{instantiation}}
115 
116 // ---------------------------------------------------------------------
117 // typeid expressions
118 // ---------------------------------------------------------------------
119 
120 // FIXME: This should really include <typeinfo>, but we don't have that yet.
121 namespace std {
122   class type_info;
123 }
124 
125 template<typename T>
126 struct TypeId0 {
127   const std::type_info &f(T* ptr) {
128     if (ptr)
129       return typeid(ptr);
130     else
131       return typeid(T);
132   }
133 };
134 
135 struct Abstract {
136   virtual void f() = 0;
137 };
138 
139 template struct TypeId0<int>;
140 template struct TypeId0<Incomplete>;
141 template struct TypeId0<Abstract>;
142 
143 // ---------------------------------------------------------------------
144 // type traits
145 // ---------------------------------------------------------------------
146 template<typename T>
147 struct is_pod {
148   static const bool value = __is_pod(T);
149 };
150 
151 static const int is_pod0[is_pod<X>::value? -1 : 1];
152 static const int is_pod1[is_pod<Y>::value? 1 : -1];
153 
154 // ---------------------------------------------------------------------
155 // initializer lists
156 // ---------------------------------------------------------------------
157 template<typename T, typename Val1>
158 struct InitList1 {
159   void f(Val1 val1) {
160     T x = { val1 };
161   }
162 };
163 
164 struct APair {
165   int *x;
166   const float *y;
167 };
168 
169 template struct InitList1<int[1], float>;
170 template struct InitList1<APair, int*>;
171 
172 template<typename T, typename Val1, typename Val2>
173 struct InitList2 {
174   void f(Val1 val1, Val2 val2) {
175     T x = { val1, val2 }; // expected-error{{incompatible}}
176   }
177 };
178 
179 template struct InitList2<APair, int*, float*>;
180 template struct InitList2<APair, int*, double*>; // expected-note{{instantiation}}
181 
182 // ---------------------------------------------------------------------
183 // member references
184 // ---------------------------------------------------------------------
185 template<typename T, typename Result>
186 struct DotMemRef0 {
187   void f(T t) {
188     Result result = t.m; // expected-error{{non-const lvalue reference to type}}
189   }
190 };
191 
192 struct MemInt {
193   int m;
194 };
195 
196 struct InheritsMemInt : MemInt { };
197 
198 struct MemIntFunc {
199   static int m(int);
200 };
201 
202 template struct DotMemRef0<MemInt, int&>;
203 template struct DotMemRef0<InheritsMemInt, int&>;
204 template struct DotMemRef0<MemIntFunc, int (*)(int)>;
205 template struct DotMemRef0<MemInt, float&>; // expected-note{{instantiation}}
206 
207 template<typename T, typename Result>
208 struct ArrowMemRef0 {
209   void f(T t) {
210     Result result = t->m; // expected-error 2{{non-const lvalue reference}}
211   }
212 };
213 
214 template<typename T>
215 struct ArrowWrapper {
216   T operator->();
217 };
218 
219 template struct ArrowMemRef0<MemInt*, int&>;
220 template struct ArrowMemRef0<InheritsMemInt*, int&>;
221 template struct ArrowMemRef0<MemIntFunc*, int (*)(int)>;
222 template struct ArrowMemRef0<MemInt*, float&>; // expected-note{{instantiation}}
223 
224 template struct ArrowMemRef0<ArrowWrapper<MemInt*>, int&>;
225 template struct ArrowMemRef0<ArrowWrapper<InheritsMemInt*>, int&>;
226 template struct ArrowMemRef0<ArrowWrapper<MemIntFunc*>, int (*)(int)>;
227 template struct ArrowMemRef0<ArrowWrapper<MemInt*>, float&>; // expected-note{{instantiation}}
228 template struct ArrowMemRef0<ArrowWrapper<ArrowWrapper<MemInt*> >, int&>;
229 
230 // FIXME: we should be able to return a MemInt without the reference!
231 MemInt &createMemInt(int);
232 
233 template<int N>
234 struct NonDepMemberExpr0 {
235   void f() {
236     createMemInt(N).m = N;
237   }
238 };
239 
240 template struct NonDepMemberExpr0<0>;
241 
242 template<typename T, typename Result>
243 struct MemberFuncCall0 {
244   void f(T t) {
245     Result result = t.f();
246   }
247 };
248 
249 template<typename T>
250 struct HasMemFunc0 {
251   T f();
252 };
253 
254 
255 template struct MemberFuncCall0<HasMemFunc0<int&>, const int&>;
256 
257 template<typename Result>
258 struct ThisMemberFuncCall0 {
259   Result g();
260 
261   void f() {
262     Result r1 = g();
263     Result r2 = this->g();
264   }
265 };
266 
267 template struct ThisMemberFuncCall0<int&>;
268 
269 template<typename T>
270 struct NonDepMemberCall0 {
271   void foo(HasMemFunc0<int&> x) {
272     T result = x.f(); // expected-error{{non-const lvalue reference}}
273   }
274 };
275 
276 template struct NonDepMemberCall0<int&>;
277 template struct NonDepMemberCall0<const int&>;
278 template struct NonDepMemberCall0<float&>; // expected-note{{instantiation}}
279 
280 
281 template<typename T>
282 struct QualifiedDeclRef0 {
283   T f() {
284     return is_pod<X>::value; // expected-error{{initialized}}
285   }
286 };
287 
288 template struct QualifiedDeclRef0<bool>;
289 template struct QualifiedDeclRef0<int&>; // expected-note{{instantiation}}
290