blob: 02b3620e7692f61fa9479223d50213617c298611 [file] [log] [blame]
George Burgess IV177399e2017-01-09 04:12:14 +00001// RUN: %clang_cc1 %s -verify -fno-builtin -std=c++14
2
3#define _diagnose_if(...) __attribute__((diagnose_if(__VA_ARGS__)))
4
George Burgess IV2b854752017-01-28 04:16:32 +00005using size_t = decltype(sizeof(int));
George Burgess IVce6284b2017-01-28 02:19:40 +00006
George Burgess IV177399e2017-01-09 04:12:14 +00007namespace type_dependent {
8template <typename T>
9void neverok() _diagnose_if(!T(), "oh no", "error") {} // expected-note 4{{from 'diagnose_if'}}
10
11template <typename T>
12void alwaysok() _diagnose_if(T(), "oh no", "error") {}
13
14template <typename T>
15void alwayswarn() _diagnose_if(!T(), "oh no", "warning") {} // expected-note 4{{from 'diagnose_if'}}
16
17template <typename T>
18void neverwarn() _diagnose_if(T(), "oh no", "warning") {}
19
20void runAll() {
21 alwaysok<int>();
22 alwaysok<int>();
23
24 {
25 void (*pok)() = alwaysok<int>;
26 pok = &alwaysok<int>;
27 }
28
29 neverok<int>(); // expected-error{{oh no}}
30 neverok<short>(); // expected-error{{oh no}}
31
32 {
33 void (*pok)() = neverok<int>; // expected-error{{oh no}}
34 }
35 {
36 void (*pok)();
37 pok = &neverok<int>; // expected-error{{oh no}}
38 }
39
40 alwayswarn<int>(); // expected-warning{{oh no}}
41 alwayswarn<short>(); // expected-warning{{oh no}}
42 {
43 void (*pok)() = alwayswarn<int>; // expected-warning{{oh no}}
44 pok = &alwayswarn<int>; // expected-warning{{oh no}}
45 }
46
47 neverwarn<int>();
48 neverwarn<short>();
49 {
50 void (*pok)() = neverwarn<int>;
51 pok = &neverwarn<int>;
52 }
53}
54
55template <typename T>
George Burgess IVce6284b2017-01-28 02:19:40 +000056void errorIf(T a) _diagnose_if(T() != a, "oh no", "error") {} // expected-note{{from 'diagnose_if'}}
George Burgess IV177399e2017-01-09 04:12:14 +000057
58template <typename T>
George Burgess IVce6284b2017-01-28 02:19:40 +000059void warnIf(T a) _diagnose_if(T() != a, "oh no", "warning") {} // expected-note{{from 'diagnose_if'}}
George Burgess IV177399e2017-01-09 04:12:14 +000060
61void runIf() {
62 errorIf(0);
George Burgess IVce6284b2017-01-28 02:19:40 +000063 errorIf(1); // expected-error{{oh no}}
George Burgess IV177399e2017-01-09 04:12:14 +000064
65 warnIf(0);
66 warnIf(1); // expected-warning{{oh no}}
67}
68}
69
70namespace value_dependent {
71template <int N>
72void neverok() _diagnose_if(N == 0 || N != 0, "oh no", "error") {} // expected-note 4{{from 'diagnose_if'}}
73
74template <int N>
75void alwaysok() _diagnose_if(N == 0 && N != 0, "oh no", "error") {}
76
77template <int N>
78void alwayswarn() _diagnose_if(N == 0 || N != 0, "oh no", "warning") {} // expected-note 4{{from 'diagnose_if'}}
79
80template <int N>
81void neverwarn() _diagnose_if(N == 0 && N != 0, "oh no", "warning") {}
82
83void runAll() {
84 alwaysok<0>();
85 alwaysok<1>();
86
87 {
88 void (*pok)() = alwaysok<0>;
89 pok = &alwaysok<0>;
90 }
91
92 neverok<0>(); // expected-error{{oh no}}
93 neverok<1>(); // expected-error{{oh no}}
94
95 {
96 void (*pok)() = neverok<0>; // expected-error{{oh no}}
97 }
98 {
99 void (*pok)();
100 pok = &neverok<0>; // expected-error{{oh no}}
101 }
102
103 alwayswarn<0>(); // expected-warning{{oh no}}
104 alwayswarn<1>(); // expected-warning{{oh no}}
105 {
106 void (*pok)() = alwayswarn<0>; // expected-warning{{oh no}}
107 pok = &alwayswarn<0>; // expected-warning{{oh no}}
108 }
109
110 neverwarn<0>();
111 neverwarn<1>();
112 {
113 void (*pok)() = neverwarn<0>;
114 pok = &neverwarn<0>;
115 }
116}
117
118template <int N>
George Burgess IVce6284b2017-01-28 02:19:40 +0000119void errorIf(int a) _diagnose_if(N != a, "oh no", "error") {} // expected-note{{from 'diagnose_if'}}
George Burgess IV177399e2017-01-09 04:12:14 +0000120
121template <int N>
George Burgess IVce6284b2017-01-28 02:19:40 +0000122void warnIf(int a) _diagnose_if(N != a, "oh no", "warning") {} // expected-note{{from 'diagnose_if'}}
George Burgess IV177399e2017-01-09 04:12:14 +0000123
124void runIf() {
125 errorIf<0>(0);
George Burgess IVce6284b2017-01-28 02:19:40 +0000126 errorIf<0>(1); // expected-error{{oh no}}
George Burgess IV177399e2017-01-09 04:12:14 +0000127
128 warnIf<0>(0);
129 warnIf<0>(1); // expected-warning{{oh no}}
130}
131}
132
133namespace no_overload_interaction {
134void foo(int) _diagnose_if(1, "oh no", "error"); // expected-note{{from 'diagnose_if'}}
135void foo(short);
136
137void bar(int);
138void bar(short) _diagnose_if(1, "oh no", "error");
139
George Burgess IVce6284b2017-01-28 02:19:40 +0000140void fooArg(int a) _diagnose_if(a, "oh no", "error"); // expected-note{{from 'diagnose_if'}}
141void fooArg(short);
George Burgess IV177399e2017-01-09 04:12:14 +0000142
143void barArg(int);
144void barArg(short a) _diagnose_if(a, "oh no", "error");
145
146void runAll() {
147 foo(1); // expected-error{{oh no}}
148 bar(1);
149
George Burgess IVce6284b2017-01-28 02:19:40 +0000150 fooArg(1); // expected-error{{oh no}}
George Burgess IV177399e2017-01-09 04:12:14 +0000151 barArg(1);
152
153 auto p = foo; // expected-error{{incompatible initializer of type '<overloaded function type>'}}
154}
155}
156
157namespace with_default_args {
158void foo(int a = 0) _diagnose_if(a, "oh no", "warning"); // expected-note 1{{from 'diagnose_if'}}
159void bar(int a = 1) _diagnose_if(a, "oh no", "warning"); // expected-note 2{{from 'diagnose_if'}}
160
161void runAll() {
162 foo();
163 foo(0);
164 foo(1); // expected-warning{{oh no}}
165
166 bar(); // expected-warning{{oh no}}
167 bar(0);
168 bar(1); // expected-warning{{oh no}}
169}
170}
171
172namespace naked_mem_expr {
173struct Foo {
174 void foo(int a) _diagnose_if(a, "should warn", "warning"); // expected-note{{from 'diagnose_if'}}
175 void bar(int a) _diagnose_if(a, "oh no", "error"); // expected-note{{from 'diagnose_if'}}
176};
177
178void runFoo() {
179 Foo().foo(0);
180 Foo().foo(1); // expected-warning{{should warn}}
181
182 Foo().bar(0);
183 Foo().bar(1); // expected-error{{oh no}}
184}
185}
186
187namespace class_template {
188template <typename T>
189struct Errors {
190 void foo(int i) _diagnose_if(i, "bad i", "error"); // expected-note{{from 'diagnose_if'}}
191 void bar(int i) _diagnose_if(i != T(), "bad i", "error"); // expected-note{{from 'diagnose_if'}}
192
George Burgess IVce6284b2017-01-28 02:19:40 +0000193 void fooOvl(int i) _diagnose_if(i, "int bad i", "error"); // expected-note{{from 'diagnose_if'}}
194 void fooOvl(short i) _diagnose_if(i, "short bad i", "error"); // expected-note{{from 'diagnose_if'}}
George Burgess IV177399e2017-01-09 04:12:14 +0000195
George Burgess IVce6284b2017-01-28 02:19:40 +0000196 void barOvl(int i) _diagnose_if(i != T(), "int bad i", "error"); // expected-note{{from 'diagnose_if'}}
197 void barOvl(short i) _diagnose_if(i != T(), "short bad i", "error"); // expected-note{{from 'diagnose_if'}}
George Burgess IV177399e2017-01-09 04:12:14 +0000198};
199
200void runErrors() {
201 Errors<int>().foo(0);
202 Errors<int>().foo(1); // expected-error{{bad i}}
203
204 Errors<int>().bar(0);
205 Errors<int>().bar(1); // expected-error{{bad i}}
206
207 Errors<int>().fooOvl(0);
George Burgess IVce6284b2017-01-28 02:19:40 +0000208 Errors<int>().fooOvl(1); // expected-error{{int bad i}}
George Burgess IV177399e2017-01-09 04:12:14 +0000209 Errors<int>().fooOvl(short(0));
George Burgess IVce6284b2017-01-28 02:19:40 +0000210 Errors<int>().fooOvl(short(1)); // expected-error{{short bad i}}
George Burgess IV177399e2017-01-09 04:12:14 +0000211
212 Errors<int>().barOvl(0);
George Burgess IVce6284b2017-01-28 02:19:40 +0000213 Errors<int>().barOvl(1); // expected-error{{int bad i}}
George Burgess IV177399e2017-01-09 04:12:14 +0000214 Errors<int>().barOvl(short(0));
George Burgess IVce6284b2017-01-28 02:19:40 +0000215 Errors<int>().barOvl(short(1)); // expected-error{{short bad i}}
George Burgess IV177399e2017-01-09 04:12:14 +0000216}
217
218template <typename T>
219struct Warnings {
220 void foo(int i) _diagnose_if(i, "bad i", "warning"); // expected-note{{from 'diagnose_if'}}
221 void bar(int i) _diagnose_if(i != T(), "bad i", "warning"); // expected-note{{from 'diagnose_if'}}
222
223 void fooOvl(int i) _diagnose_if(i, "int bad i", "warning"); // expected-note{{from 'diagnose_if'}}
224 void fooOvl(short i) _diagnose_if(i, "short bad i", "warning"); // expected-note{{from 'diagnose_if'}}
225
226 void barOvl(int i) _diagnose_if(i != T(), "int bad i", "warning"); // expected-note{{from 'diagnose_if'}}
227 void barOvl(short i) _diagnose_if(i != T(), "short bad i", "warning"); // expected-note{{from 'diagnose_if'}}
228};
229
230void runWarnings() {
231 Warnings<int>().foo(0);
232 Warnings<int>().foo(1); // expected-warning{{bad i}}
233
234 Warnings<int>().bar(0);
235 Warnings<int>().bar(1); // expected-warning{{bad i}}
236
237 Warnings<int>().fooOvl(0);
238 Warnings<int>().fooOvl(1); // expected-warning{{int bad i}}
239 Warnings<int>().fooOvl(short(0));
240 Warnings<int>().fooOvl(short(1)); // expected-warning{{short bad i}}
241
242 Warnings<int>().barOvl(0);
243 Warnings<int>().barOvl(1); // expected-warning{{int bad i}}
244 Warnings<int>().barOvl(short(0));
245 Warnings<int>().barOvl(short(1)); // expected-warning{{short bad i}}
246}
247}
248
249namespace template_specialization {
250template <typename T>
251struct Foo {
252 void foo() _diagnose_if(1, "override me", "error"); // expected-note{{from 'diagnose_if'}}
253 void bar(int i) _diagnose_if(i, "bad i", "error"); // expected-note{{from 'diagnose_if'}}
254 void baz(int i);
255};
256
257template <>
258struct Foo<int> {
259 void foo();
260 void bar(int i);
261 void baz(int i) _diagnose_if(i, "bad i", "error"); // expected-note{{from 'diagnose_if'}}
262};
263
264void runAll() {
265 Foo<double>().foo(); // expected-error{{override me}}
266 Foo<int>().foo();
267
268 Foo<double>().bar(1); // expected-error{{bad i}}
269 Foo<int>().bar(1);
270
271 Foo<double>().baz(1);
272 Foo<int>().baz(1); // expected-error{{bad i}}
273}
274}
275
276namespace late_constexpr {
277constexpr int foo();
278constexpr int foo(int a);
279
George Burgess IVce6284b2017-01-28 02:19:40 +0000280void bar() _diagnose_if(foo(), "bad foo", "error"); // expected-note{{from 'diagnose_if'}}
281void bar(int a) _diagnose_if(foo(a), "bad foo", "error"); // expected-note{{from 'diagnose_if'}}
George Burgess IV177399e2017-01-09 04:12:14 +0000282
283void early() {
284 bar();
285 bar(0);
286 bar(1);
287}
288
289constexpr int foo() { return 1; }
290constexpr int foo(int a) { return a; }
291
292void late() {
293 bar(); // expected-error{{bad foo}}
294 bar(0);
George Burgess IVce6284b2017-01-28 02:19:40 +0000295 bar(1); // expected-error{{bad foo}}
George Burgess IV177399e2017-01-09 04:12:14 +0000296}
297}
298
299namespace late_parsed {
300struct Foo {
301 int i;
302 constexpr Foo(int i): i(i) {}
303 constexpr bool isFooable() const { return i; }
304
305 void go() const _diagnose_if(isFooable(), "oh no", "error") {} // expected-note{{from 'diagnose_if'}}
George Burgess IVce6284b2017-01-28 02:19:40 +0000306 operator int() const _diagnose_if(isFooable(), "oh no", "error") { return 1; } // expected-note{{from 'diagnose_if'}}
George Burgess IV177399e2017-01-09 04:12:14 +0000307
George Burgess IVce6284b2017-01-28 02:19:40 +0000308 void go2() const _diagnose_if(isFooable(), "oh no", "error") // expected-note{{from 'diagnose_if'}}
George Burgess IV177399e2017-01-09 04:12:14 +0000309 __attribute__((enable_if(true, ""))) {}
George Burgess IVce6284b2017-01-28 02:19:40 +0000310 void go2() const _diagnose_if(isFooable(), "oh no", "error") {}
George Burgess IV177399e2017-01-09 04:12:14 +0000311
312 constexpr int go3() const _diagnose_if(isFooable(), "oh no", "error")
313 __attribute__((enable_if(true, ""))) {
314 return 1;
315 }
316
317 constexpr int go4() const _diagnose_if(isFooable(), "oh no", "error") {
318 return 1;
319 }
320 constexpr int go4() const _diagnose_if(isFooable(), "oh no", "error")
321 __attribute__((enable_if(true, ""))) {
322 return 1;
323 }
324
325 // We hope to support emitting these errors in the future. For now, though...
326 constexpr int runGo() const {
327 return go3() + go4();
328 }
329};
330
George Burgess IVce6284b2017-01-28 02:19:40 +0000331void go(const Foo &f) _diagnose_if(f.isFooable(), "oh no", "error") {} // expected-note{{from 'diagnose_if'}}
George Burgess IV177399e2017-01-09 04:12:14 +0000332
333void run() {
334 Foo(0).go();
335 Foo(1).go(); // expected-error{{oh no}}
336
337 (void)int(Foo(0));
George Burgess IVce6284b2017-01-28 02:19:40 +0000338 (void)int(Foo(1)); // expected-error{{oh no}}
George Burgess IV177399e2017-01-09 04:12:14 +0000339
340 Foo(0).go2();
George Burgess IVce6284b2017-01-28 02:19:40 +0000341 Foo(1).go2(); // expected-error{{oh no}}
George Burgess IV177399e2017-01-09 04:12:14 +0000342
343 go(Foo(0));
George Burgess IVce6284b2017-01-28 02:19:40 +0000344 go(Foo(1)); // expected-error{{oh no}}
George Burgess IV177399e2017-01-09 04:12:14 +0000345}
346}
347
348namespace member_templates {
349struct Foo {
350 int i;
351 constexpr Foo(int i): i(i) {}
352 constexpr bool bad() const { return i; }
353
George Burgess IVce6284b2017-01-28 02:19:40 +0000354 template <typename T> T getVal() _diagnose_if(bad(), "oh no", "error") { // expected-note{{from 'diagnose_if'}}
George Burgess IV177399e2017-01-09 04:12:14 +0000355 return T();
356 }
357
358 template <typename T>
George Burgess IVce6284b2017-01-28 02:19:40 +0000359 constexpr T getVal2() const _diagnose_if(bad(), "oh no", "error") { // expected-note{{from 'diagnose_if'}}
George Burgess IV177399e2017-01-09 04:12:14 +0000360 return T();
361 }
362
363 template <typename T>
George Burgess IVce6284b2017-01-28 02:19:40 +0000364 constexpr operator T() const _diagnose_if(bad(), "oh no", "error") { // expected-note{{from 'diagnose_if'}}
George Burgess IV177399e2017-01-09 04:12:14 +0000365 return T();
366 }
367
368 // We hope to support emitting these errors in the future.
369 int run() { return getVal<int>() + getVal2<int>() + int(*this); }
370};
371
372void run() {
373 Foo(0).getVal<int>();
George Burgess IVce6284b2017-01-28 02:19:40 +0000374 Foo(1).getVal<int>(); // expected-error{{oh no}}
George Burgess IV177399e2017-01-09 04:12:14 +0000375
376 Foo(0).getVal2<int>();
George Burgess IVce6284b2017-01-28 02:19:40 +0000377 Foo(1).getVal2<int>(); // expected-error{{oh no}}
George Burgess IV177399e2017-01-09 04:12:14 +0000378
379 (void)int(Foo(0));
George Burgess IVce6284b2017-01-28 02:19:40 +0000380 (void)int(Foo(1)); // expected-error{{oh no}}
George Burgess IV177399e2017-01-09 04:12:14 +0000381}
382}
383
384namespace special_member_operators {
385struct Bar { int j; };
386struct Foo {
387 int i;
388 constexpr Foo(int i): i(i) {}
389 constexpr bool bad() const { return i; }
George Burgess IVce6284b2017-01-28 02:19:40 +0000390 const Bar *operator->() const _diagnose_if(bad(), "oh no", "error") { // expected-note{{from 'diagnose_if'}}
George Burgess IV177399e2017-01-09 04:12:14 +0000391 return nullptr;
392 }
George Burgess IVce6284b2017-01-28 02:19:40 +0000393 void operator()() const _diagnose_if(bad(), "oh no", "error") {} // expected-note{{from 'diagnose_if'}}
George Burgess IV177399e2017-01-09 04:12:14 +0000394};
395
396struct ParenOverload {
397 int i;
398 constexpr ParenOverload(int i): i(i) {}
399 constexpr bool bad() const { return i; }
George Burgess IVce6284b2017-01-28 02:19:40 +0000400 void operator()(double) const _diagnose_if(bad(), "oh no", "error") {} // expected-note{{from 'diagnose_if'}}
401 void operator()(int) const _diagnose_if(bad(), "oh no", "error") {} // expected-note{{from 'diagnose_if'}}
George Burgess IV177399e2017-01-09 04:12:14 +0000402};
403
404struct ParenTemplate {
405 int i;
406 constexpr ParenTemplate(int i): i(i) {}
407 constexpr bool bad() const { return i; }
408 template <typename T>
George Burgess IVce6284b2017-01-28 02:19:40 +0000409 void operator()(T) const _diagnose_if(bad(), "oh no", "error") {} // expected-note 2{{from 'diagnose_if'}}
George Burgess IV177399e2017-01-09 04:12:14 +0000410};
411
412void run() {
413 (void)Foo(0)->j;
George Burgess IVce6284b2017-01-28 02:19:40 +0000414 (void)Foo(1)->j; // expected-error{{oh no}}
George Burgess IV177399e2017-01-09 04:12:14 +0000415
416 Foo(0)();
George Burgess IVce6284b2017-01-28 02:19:40 +0000417 Foo(1)(); // expected-error{{oh no}}
George Burgess IV177399e2017-01-09 04:12:14 +0000418
419 ParenOverload(0)(1);
420 ParenOverload(0)(1.);
421
George Burgess IVce6284b2017-01-28 02:19:40 +0000422 ParenOverload(1)(1); // expected-error{{oh no}}
423 ParenOverload(1)(1.); // expected-error{{oh no}}
George Burgess IV177399e2017-01-09 04:12:14 +0000424
425 ParenTemplate(0)(1);
426 ParenTemplate(0)(1.);
427
George Burgess IVce6284b2017-01-28 02:19:40 +0000428 ParenTemplate(1)(1); // expected-error{{oh no}}
429 ParenTemplate(1)(1.); // expected-error{{oh no}}
George Burgess IV177399e2017-01-09 04:12:14 +0000430}
431
432void runLambda() {
George Burgess IVce6284b2017-01-28 02:19:40 +0000433 auto L1 = [](int i) _diagnose_if(i, "oh no", "error") {}; // expected-note{{from 'diagnose_if'}}
George Burgess IV177399e2017-01-09 04:12:14 +0000434 L1(0);
George Burgess IVce6284b2017-01-28 02:19:40 +0000435 L1(1); // expected-error{{oh no}}
436}
437
438struct Brackets {
439 int i;
440 constexpr Brackets(int i): i(i) {}
441 void operator[](int) _diagnose_if(i == 1, "oh no", "warning") // expected-note{{from 'diagnose_if'}}
442 _diagnose_if(i == 2, "oh no", "error"); // expected-note{{from 'diagnose_if'}}
443};
444
445void runBrackets(int i) {
446 Brackets{0}[i];
447 Brackets{1}[i]; // expected-warning{{oh no}}
448 Brackets{2}[i]; // expected-error{{oh no}}
449}
450
451struct Unary {
452 int i;
453 constexpr Unary(int i): i(i) {}
454 void operator+() _diagnose_if(i == 1, "oh no", "warning") // expected-note{{from 'diagnose_if'}}
455 _diagnose_if(i == 2, "oh no", "error"); // expected-note{{from 'diagnose_if'}}
456};
457
458void runUnary() {
459 +Unary{0};
460 +Unary{1}; // expected-warning{{oh no}}
461 +Unary{2}; // expected-error{{oh no}}
462}
463
464struct PostInc {
465 void operator++(int i) _diagnose_if(i == 1, "oh no", "warning") // expected-note{{from 'diagnose_if'}}
466 _diagnose_if(i == 2, "oh no", "error"); // expected-note{{from 'diagnose_if'}}
467};
468
469void runPostInc() {
470 PostInc{}++;
471 PostInc{}.operator++(1); // expected-warning{{oh no}}
472 PostInc{}.operator++(2); // expected-error{{oh no}}
George Burgess IV177399e2017-01-09 04:12:14 +0000473}
474}
475
476namespace ctors {
477struct Foo {
478 int I;
479 constexpr Foo(int I): I(I) {}
480
George Burgess IVce6284b2017-01-28 02:19:40 +0000481 constexpr const Foo &operator=(const Foo &) const
482 _diagnose_if(I, "oh no", "error") { // expected-note{{from 'diagnose_if'}}
George Burgess IV177399e2017-01-09 04:12:14 +0000483 return *this;
484 }
485
George Burgess IVce6284b2017-01-28 02:19:40 +0000486 constexpr const Foo &operator=(const Foo &&) const
487 _diagnose_if(I, "oh no", "error") { // expected-note{{from 'diagnose_if'}}
George Burgess IV177399e2017-01-09 04:12:14 +0000488 return *this;
489 }
490};
491
George Burgess IVce6284b2017-01-28 02:19:40 +0000492struct Bar {
493 int I;
494 constexpr Bar(int I) _diagnose_if(I == 1, "oh no", "warning") // expected-note{{from 'diagnose_if'}}
495 _diagnose_if(I == 2, "oh no", "error"): I(I) {} // expected-note{{from 'diagnose_if'}}
496};
497
George Burgess IV177399e2017-01-09 04:12:14 +0000498void run() {
499 constexpr Foo F{0};
500 constexpr Foo F2{1};
501
George Burgess IVce6284b2017-01-28 02:19:40 +0000502 F2 = F; // expected-error{{oh no}}
503 F2 = Foo{2}; // expected-error{{oh no}}
504
505 Bar{0};
506 Bar{1}; // expected-warning{{oh no}}
507 Bar{2}; // expected-error{{oh no}}
508}
509}
510
511namespace ref_init {
512struct Bar {};
513struct Baz {};
514struct Foo {
515 int i;
516 constexpr Foo(int i): i(i) {}
517 operator const Bar &() const _diagnose_if(i, "oh no", "warning"); // expected-note{{from 'diagnose_if'}}
518 operator const Baz &() const _diagnose_if(i, "oh no", "error"); // expected-note{{from 'diagnose_if'}}
519};
520void fooBar(const Bar &b);
521void fooBaz(const Baz &b);
522
523void run() {
524 fooBar(Foo{0});
525 fooBar(Foo{1}); // expected-warning{{oh no}}
526 fooBaz(Foo{0});
527 fooBaz(Foo{1}); // expected-error{{oh no}}
528}
529}
530
531namespace udl {
532void operator""_fn(char c)_diagnose_if(c == 1, "oh no", "warning") // expected-note{{from 'diagnose_if'}}
533 _diagnose_if(c == 2, "oh no", "error"); // expected-note{{from 'diagnose_if'}}
534
535void run() {
536 '\0'_fn;
537 '\1'_fn; // expected-warning{{oh no}}
538 '\2'_fn; // expected-error{{oh no}}
539}
540}
541
542namespace PR31638 {
543struct String {
544 String(char const* __s) _diagnose_if(__s == nullptr, "oh no ptr", "warning"); // expected-note{{from 'diagnose_if'}}
545 String(int __s) _diagnose_if(__s != 0, "oh no int", "warning"); // expected-note{{from 'diagnose_if'}}
546};
547
548void run() {
549 String s(nullptr); // expected-warning{{oh no ptr}}
550 String ss(42); // expected-warning{{oh no int}}
551}
552}
553
554namespace PR31639 {
555struct Foo {
556 Foo(int I) __attribute__((diagnose_if(I, "oh no", "error"))); // expected-note{{from 'diagnose_if'}}
557};
558
559void bar() { Foo f(1); } // expected-error{{oh no}}
560}
561
562namespace user_defined_conversion {
563struct Foo {
564 int i;
565 constexpr Foo(int i): i(i) {}
566 operator size_t() const _diagnose_if(i == 1, "oh no", "warning") // expected-note{{from 'diagnose_if'}}
567 _diagnose_if(i == 2, "oh no", "error"); // expected-note{{from 'diagnose_if'}}
568};
569
570void run() {
571 // `new T[N]`, where N is implicitly convertible to size_t, calls
572 // PerformImplicitConversion directly. This lets us test the diagnostic logic
573 // in PerformImplicitConversion.
574 new int[Foo{0}];
575 new int[Foo{1}]; // expected-warning{{oh no}}
576 new int[Foo{2}]; // expected-error{{oh no}}
577}
578}
579
580namespace std {
581 template <typename T>
582 struct initializer_list {
583 const T *ptr;
584 size_t elems;
585
586 constexpr size_t size() const { return elems; }
587 };
588}
589
590namespace initializer_lists {
591struct Foo {
592 Foo(std::initializer_list<int> l)
593 _diagnose_if(l.size() == 1, "oh no", "warning") // expected-note{{from 'diagnose_if'}}
594 _diagnose_if(l.size() == 2, "oh no", "error") {} // expected-note{{from 'diagnose_if'}}
595};
596
597void run() {
598 Foo{std::initializer_list<int>{}};
599 Foo{std::initializer_list<int>{1}}; // expected-warning{{oh no}}
600 Foo{std::initializer_list<int>{1, 2}}; // expected-error{{oh no}}
601 Foo{std::initializer_list<int>{1, 2, 3}};
602}
603}
604
605namespace range_for_loop {
606 namespace adl {
607 struct Foo {
608 int i;
609 constexpr Foo(int i): i(i) {}
610 };
611 void **begin(const Foo &f) _diagnose_if(f.i, "oh no", "warning");
612 void **end(const Foo &f) _diagnose_if(f.i, "oh no", "warning");
613
614 struct Bar {
615 int i;
616 constexpr Bar(int i): i(i) {}
617 };
618 void **begin(const Bar &b) _diagnose_if(b.i, "oh no", "error");
619 void **end(const Bar &b) _diagnose_if(b.i, "oh no", "error");
620 }
621
622 void run() {
623 for (void *p : adl::Foo(0)) {}
624 // FIXME: This should emit diagnostics. It seems that our constexpr
625 // evaluator isn't able to evaluate `adl::Foo(1)` as a constant, though.
626 for (void *p : adl::Foo(1)) {}
627
628 for (void *p : adl::Bar(0)) {}
629 // FIXME: Same thing.
630 for (void *p : adl::Bar(1)) {}
631 }
632}
633
634namespace operator_new {
635struct Foo {
636 int j;
637 static void *operator new(size_t i) _diagnose_if(i, "oh no", "warning");
638};
639
640struct Bar {
641 int j;
642 static void *operator new(size_t i) _diagnose_if(!i, "oh no", "warning");
643};
644
645void run() {
646 // FIXME: This should emit a diagnostic.
647 new Foo();
648 // This is here because we sometimes pass a dummy argument `operator new`. We
649 // should ignore this, rather than complaining about it.
650 new Bar();
651}
652}
653
654namespace contextual_implicit_conv {
655struct Foo {
656 int i;
657 constexpr Foo(int i): i(i) {}
658 constexpr operator int() const _diagnose_if(i == 1, "oh no", "warning") // expected-note{{from 'diagnose_if'}}
659 _diagnose_if(i == 2, "oh no", "error") { // expected-note{{from 'diagnose_if'}}
660 return i;
661 }
662};
663
664void run() {
665 switch (constexpr Foo i = 0) { default: break; }
666 switch (constexpr Foo i = 1) { default: break; } // expected-warning{{oh no}}
667 switch (constexpr Foo i = 2) { default: break; } // expected-error{{oh no}}
George Burgess IV177399e2017-01-09 04:12:14 +0000668}
669}