1 // RUN: %clang_cc1 %s -verify -fno-builtin -std=c++14
3 #define _diagnose_if(...) __attribute__((diagnose_if(__VA_ARGS__)))
5 using size_t = decltype(sizeof(int));
7 namespace type_dependent
{
9 void neverok() _diagnose_if(!T(), "oh no", "error") {} // expected-note 4{{from 'diagnose_if'}}
12 void alwaysok() _diagnose_if(T(), "oh no", "error") {}
15 void alwayswarn() _diagnose_if(!T(), "oh no", "warning") {} // expected-note 4{{from 'diagnose_if'}}
18 void neverwarn() _diagnose_if(T(), "oh no", "warning") {}
25 void (*pok
)() = alwaysok
<int>;
29 neverok
<int>(); // expected-error{{oh no}}
30 neverok
<short>(); // expected-error{{oh no}}
33 void (*pok
)() = neverok
<int>; // expected-error{{oh no}}
37 pok
= &neverok
<int>; // expected-error{{oh no}}
40 alwayswarn
<int>(); // expected-warning{{oh no}}
41 alwayswarn
<short>(); // expected-warning{{oh no}}
43 void (*pok
)() = alwayswarn
<int>; // expected-warning{{oh no}}
44 pok
= &alwayswarn
<int>; // expected-warning{{oh no}}
50 void (*pok
)() = neverwarn
<int>;
51 pok
= &neverwarn
<int>;
56 void errorIf(T a
) _diagnose_if(T() != a
, "oh no", "error") {} // expected-note{{from 'diagnose_if'}}
59 void warnIf(T a
) _diagnose_if(T() != a
, "oh no", "warning") {} // expected-note{{from 'diagnose_if'}}
63 errorIf(1); // expected-error{{oh no}}
66 warnIf(1); // expected-warning{{oh no}}
70 namespace value_dependent
{
72 void neverok() _diagnose_if(N
== 0 || N
!= 0, "oh no", "error") {} // expected-note 4{{from 'diagnose_if'}}
75 void alwaysok() _diagnose_if(N
== 0 && N
!= 0, "oh no", "error") {}
78 void alwayswarn() _diagnose_if(N
== 0 || N
!= 0, "oh no", "warning") {} // expected-note 4{{from 'diagnose_if'}}
81 void neverwarn() _diagnose_if(N
== 0 && N
!= 0, "oh no", "warning") {}
88 void (*pok
)() = alwaysok
<0>;
92 neverok
<0>(); // expected-error{{oh no}}
93 neverok
<1>(); // expected-error{{oh no}}
96 void (*pok
)() = neverok
<0>; // expected-error{{oh no}}
100 pok
= &neverok
<0>; // expected-error{{oh no}}
103 alwayswarn
<0>(); // expected-warning{{oh no}}
104 alwayswarn
<1>(); // expected-warning{{oh no}}
106 void (*pok
)() = alwayswarn
<0>; // expected-warning{{oh no}}
107 pok
= &alwayswarn
<0>; // expected-warning{{oh no}}
113 void (*pok
)() = neverwarn
<0>;
119 void errorIf(int a
) _diagnose_if(N
!= a
, "oh no", "error") {} // expected-note{{from 'diagnose_if'}}
122 void warnIf(int a
) _diagnose_if(N
!= a
, "oh no", "warning") {} // expected-note{{from 'diagnose_if'}}
126 errorIf
<0>(1); // expected-error{{oh no}}
129 warnIf
<0>(1); // expected-warning{{oh no}}
133 namespace no_overload_interaction
{
134 void foo(int) _diagnose_if(1, "oh no", "error"); // expected-note{{from 'diagnose_if'}}
138 void bar(short) _diagnose_if(1, "oh no", "error");
140 void fooArg(int a
) _diagnose_if(a
, "oh no", "error"); // expected-note{{from 'diagnose_if'}}
144 void barArg(short a
) _diagnose_if(a
, "oh no", "error");
147 foo(1); // expected-error{{oh no}}
150 fooArg(1); // expected-error{{oh no}}
153 auto p
= foo
; // expected-error{{incompatible initializer of type '<overloaded function type>'}}
157 namespace with_default_args
{
158 void foo(int a
= 0) _diagnose_if(a
, "oh no", "warning"); // expected-note 1{{from 'diagnose_if'}}
159 void bar(int a
= 1) _diagnose_if(a
, "oh no", "warning"); // expected-note 2{{from 'diagnose_if'}}
164 foo(1); // expected-warning{{oh no}}
166 bar(); // expected-warning{{oh no}}
168 bar(1); // expected-warning{{oh no}}
172 namespace naked_mem_expr
{
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'}}
180 Foo().foo(1); // expected-warning{{should warn}}
183 Foo().bar(1); // expected-error{{oh no}}
187 namespace class_template
{
188 template <typename T
>
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'}}
193 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'}}
196 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'}}
201 Errors
<int>().foo(0);
202 Errors
<int>().foo(1); // expected-error{{bad i}}
204 Errors
<int>().bar(0);
205 Errors
<int>().bar(1); // expected-error{{bad i}}
207 Errors
<int>().fooOvl(0);
208 Errors
<int>().fooOvl(1); // expected-error{{int bad i}}
209 Errors
<int>().fooOvl(short(0));
210 Errors
<int>().fooOvl(short(1)); // expected-error{{short bad i}}
212 Errors
<int>().barOvl(0);
213 Errors
<int>().barOvl(1); // expected-error{{int bad i}}
214 Errors
<int>().barOvl(short(0));
215 Errors
<int>().barOvl(short(1)); // expected-error{{short bad i}}
218 template <typename T
>
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'}}
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'}}
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'}}
231 Warnings
<int>().foo(0);
232 Warnings
<int>().foo(1); // expected-warning{{bad i}}
234 Warnings
<int>().bar(0);
235 Warnings
<int>().bar(1); // expected-warning{{bad i}}
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}}
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}}
249 namespace template_specialization
{
250 template <typename T
>
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'}}
261 void baz(int i
) _diagnose_if(i
, "bad i", "error"); // expected-note{{from 'diagnose_if'}}
265 Foo
<double>().foo(); // expected-error{{override me}}
268 Foo
<double>().bar(1); // expected-error{{bad i}}
271 Foo
<double>().baz(1);
272 Foo
<int>().baz(1); // expected-error{{bad i}}
276 namespace late_constexpr
{
278 constexpr int foo(int a
);
280 void bar() _diagnose_if(foo(), "bad foo", "error"); // expected-note{{from 'diagnose_if'}}
281 void bar(int a
) _diagnose_if(foo(a
), "bad foo", "error"); // expected-note{{from 'diagnose_if'}}
289 constexpr int foo() { return 1; }
290 constexpr int foo(int a
) { return a
; }
293 bar(); // expected-error{{bad foo}}
295 bar(1); // expected-error{{bad foo}}
299 namespace late_parsed
{
302 constexpr Foo(int i
): i(i
) {}
303 constexpr bool isFooable() const { return i
; }
305 void go() const _diagnose_if(isFooable(), "oh no", "error") {} // expected-note{{from 'diagnose_if'}}
306 operator int() const _diagnose_if(isFooable(), "oh no", "error") { return 1; } // expected-note{{from 'diagnose_if'}}
308 void go2() const _diagnose_if(isFooable(), "oh no", "error") // expected-note{{from 'diagnose_if'}}
309 __attribute__((enable_if(true, ""))) {}
310 void go2() const _diagnose_if(isFooable(), "oh no", "error") {}
312 constexpr int go3() const _diagnose_if(isFooable(), "oh no", "error")
313 __attribute__((enable_if(true, ""))) {
317 constexpr int go4() const _diagnose_if(isFooable(), "oh no", "error") {
320 constexpr int go4() const _diagnose_if(isFooable(), "oh no", "error")
321 __attribute__((enable_if(true, ""))) {
325 // We hope to support emitting these errors in the future. For now, though...
326 constexpr int runGo() const {
327 return go3() + go4();
331 void go(const Foo
&f
) _diagnose_if(f
.isFooable(), "oh no", "error") {} // expected-note{{from 'diagnose_if'}}
335 Foo(1).go(); // expected-error{{oh no}}
338 (void)int(Foo(1)); // expected-error{{oh no}}
341 Foo(1).go2(); // expected-error{{oh no}}
344 go(Foo(1)); // expected-error{{oh no}}
348 namespace member_templates
{
351 constexpr Foo(int i
): i(i
) {}
352 constexpr bool bad() const { return i
; }
354 template <typename T
> T
getVal() _diagnose_if(bad(), "oh no", "error") { // expected-note{{from 'diagnose_if'}}
358 template <typename T
>
359 constexpr T
getVal2() const _diagnose_if(bad(), "oh no", "error") { // expected-note{{from 'diagnose_if'}}
363 template <typename T
>
364 constexpr operator T() const _diagnose_if(bad(), "oh no", "error") { // expected-note{{from 'diagnose_if'}}
368 // We hope to support emitting these errors in the future.
369 int run() { return getVal
<int>() + getVal2
<int>() + int(*this); }
373 Foo(0).getVal
<int>();
374 Foo(1).getVal
<int>(); // expected-error{{oh no}}
376 Foo(0).getVal2
<int>();
377 Foo(1).getVal2
<int>(); // expected-error{{oh no}}
380 (void)int(Foo(1)); // expected-error{{oh no}}
384 namespace special_member_operators
{
385 struct Bar
{ int j
; };
388 constexpr Foo(int i
): i(i
) {}
389 constexpr bool bad() const { return i
; }
390 const Bar
*operator->() const _diagnose_if(bad(), "oh no", "error") { // expected-note{{from 'diagnose_if'}}
393 void operator()() const _diagnose_if(bad(), "oh no", "error") {} // expected-note{{from 'diagnose_if'}}
396 struct ParenOverload
{
398 constexpr ParenOverload(int i
): i(i
) {}
399 constexpr bool bad() const { return i
; }
400 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'}}
404 struct ParenTemplate
{
406 constexpr ParenTemplate(int i
): i(i
) {}
407 constexpr bool bad() const { return i
; }
408 template <typename T
>
409 void operator()(T
) const _diagnose_if(bad(), "oh no", "error") {} // expected-note 2{{from 'diagnose_if'}}
414 (void)Foo(1)->j
; // expected-error{{oh no}}
417 Foo(1)(); // expected-error{{oh no}}
420 ParenOverload(0)(1.);
422 ParenOverload(1)(1); // expected-error{{oh no}}
423 ParenOverload(1)(1.); // expected-error{{oh no}}
426 ParenTemplate(0)(1.);
428 ParenTemplate(1)(1); // expected-error{{oh no}}
429 ParenTemplate(1)(1.); // expected-error{{oh no}}
433 auto L1
= [](int i
) _diagnose_if(i
, "oh no", "error") {}; // expected-note{{from 'diagnose_if'}}
435 L1(1); // expected-error{{oh no}}
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'}}
445 void runBrackets(int i
) {
447 Brackets
{1}[i
]; // expected-warning{{oh no}}
448 Brackets
{2}[i
]; // expected-error{{oh no}}
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'}}
460 +Unary
{1}; // expected-warning{{oh no}}
461 +Unary
{2}; // expected-error{{oh no}}
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'}}
471 PostInc
{}.operator++(1); // expected-warning{{oh no}}
472 PostInc
{}.operator++(2); // expected-error{{oh no}}
479 constexpr Foo(int I
): I(I
) {}
481 constexpr const Foo
&operator=(const Foo
&) const
482 _diagnose_if(I
, "oh no", "error") { // expected-note{{from 'diagnose_if'}}
486 constexpr const Foo
&operator=(const Foo
&&) const
487 _diagnose_if(I
, "oh no", "error") { // expected-note{{from 'diagnose_if'}}
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'}}
502 F2
= F
; // expected-error{{oh no}}
503 F2
= Foo
{2}; // expected-error{{oh no}}
506 Bar
{1}; // expected-warning{{oh no}}
507 Bar
{2}; // expected-error{{oh no}}
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'}}
520 void fooBar(const Bar
&b
);
521 void fooBaz(const Baz
&b
);
525 fooBar(Foo
{1}); // expected-warning{{oh no}}
527 fooBaz(Foo
{1}); // expected-error{{oh no}}
532 void 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'}}
537 '\1'_fn
; // expected-warning{{oh no}}
538 '\2'_fn
; // expected-error{{oh no}}
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'}}
549 String
s(nullptr); // expected-warning{{oh no ptr}}
550 String
ss(42); // expected-warning{{oh no int}}
556 Foo(int I
) __attribute__((diagnose_if(I
, "oh no", "error"))); // expected-note{{from 'diagnose_if'}}
559 void bar() { Foo
f(1); } // expected-error{{oh no}}
562 namespace user_defined_conversion
{
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'}}
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.
575 new int[Foo
{1}]; // expected-warning{{oh no}}
576 new int[Foo
{2}]; // expected-error{{oh no}}
581 template <typename T
>
582 struct initializer_list
{
586 constexpr size_t size() const { return elems
; }
590 namespace initializer_lists
{
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'}}
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}};
605 namespace range_for_loop
{
609 constexpr Foo(int i
): i(i
) {}
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");
616 constexpr Bar(int i
): i(i
) {}
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");
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)) {}
628 for (void *p
: adl::Bar(0)) {}
629 // FIXME: Same thing.
630 for (void *p
: adl::Bar(1)) {}
634 namespace operator_new
{
637 static void *operator new(size_t i
) _diagnose_if(i
, "oh no", "warning"); // expected-note{{from 'diagnose_if'}}
642 static void *operator new(size_t i
) _diagnose_if(!i
, "oh no", "warning");
646 new Foo(); // expected-warning{{oh no}}
651 namespace contextual_implicit_conv
{
654 constexpr Foo(int i
): i(i
) {}
655 constexpr operator int() const _diagnose_if(i
== 1, "oh no", "warning") // expected-note{{from 'diagnose_if'}}
656 _diagnose_if(i
== 2, "oh no", "error") { // expected-note{{from 'diagnose_if'}}
662 switch (constexpr Foo i
= 0) { default: break; }
663 switch (constexpr Foo i
= 1) { default: break; } // expected-warning{{oh no}}
664 switch (constexpr Foo i
= 2) { default: break; } // expected-error{{oh no}}