1 // RUN: %clang_cc1 %s -verify -fno-builtin
3 #define _diagnose_if(...) __attribute__((diagnose_if(__VA_ARGS__)))
5 void failure1(void) _diagnose_if(); // expected-error{{exactly 3 arguments}}
6 void failure2(void) _diagnose_if(0); // expected-error{{exactly 3 arguments}}
7 void failure3(void) _diagnose_if(0, ""); // expected-error{{exactly 3 arguments}}
8 void failure4(void) _diagnose_if(0, "", "error", 1); // expected-error{{exactly 3 arguments}}
9 void failure5(void) _diagnose_if(0, 0, "error"); // expected-error{{requires a string}}
10 void failure6(void) _diagnose_if(0, "", "invalid"); // expected-error{{invalid diagnostic type for 'diagnose_if'; use "error" or "warning" instead}}
11 void failure7(void) _diagnose_if(0, "", "ERROR"); // expected-error{{invalid diagnostic type}}
12 void failure8(int a
) _diagnose_if(a
, "", ""); // expected-error{{invalid diagnostic type}}
13 void failure9(void) _diagnose_if(a
, "", ""); // expected-error{{undeclared identifier 'a'}}
16 void never_constant(void) _diagnose_if(globalVar
, "", "error"); // expected-error{{'diagnose_if' attribute expression never produces a constant expression}} expected-note{{subexpression not valid}}
17 void never_constant(void) _diagnose_if(globalVar
, "", "warning"); // expected-error{{'diagnose_if' attribute expression never produces a constant expression}} expected-note{{subexpression not valid}}
19 int alwaysok(int q
) _diagnose_if(0, "", "error");
20 int neverok(int q
) _diagnose_if(1, "oh no", "error"); // expected-note 5{{from 'diagnose_if' attribute on 'neverok'}}
21 int alwayswarn(int q
) _diagnose_if(1, "oh no", "warning"); // expected-note 5{{from 'diagnose_if' attribute}}
22 int neverwarn(int q
) _diagnose_if(0, "", "warning");
24 void runConstant(void) {
31 int (*pok
)(int) = alwaysok
;
35 neverok(0); // expected-error{{oh no}}
36 neverok(1); // expected-error{{oh no}}
37 neverok(m
); // expected-error{{oh no}}
39 int (*pok
)(int) = neverok
; // expected-error{{oh no}}
40 pok
= &neverok
; // expected-error{{oh no}}
43 alwayswarn(0); // expected-warning{{oh no}}
44 alwayswarn(1); // expected-warning{{oh no}}
45 alwayswarn(m
); // expected-warning{{oh no}}
47 int (*pok
)(int) = alwayswarn
; // expected-warning{{oh no}}
48 pok
= &alwayswarn
; // expected-warning{{oh no}}
55 int (*pok
)(int) = neverwarn
;
60 int abs(int q
) _diagnose_if(q
>= 0, "redundant abs call", "error"); //expected-note{{from 'diagnose_if'}}
61 void runVariable(void) {
64 abs(1); // expected-error{{redundant abs call}}
67 int (*pabs
)(int) = abs
;
71 #define _overloadable __attribute__((overloadable))
73 int ovl1(const char *n
) _overloadable
_diagnose_if(n
, "oh no", "error"); // expected-note{{from 'diagnose_if'}}
74 int ovl1(void *m
) _overloadable
;
76 int ovl2(const char *n
) _overloadable
_diagnose_if(n
, "oh no", "error"); // expected-note{{candidate function}}
77 int ovl2(char *m
) _overloadable
; // expected-note{{candidate function}}
78 void overloadsYay(void) {
80 ovl1(""); // expected-error{{oh no}}
82 ovl2((void *)0); // expected-error{{ambiguous}}
85 void errorWarnDiagnose1(void) _diagnose_if(1, "oh no", "error") // expected-note{{from 'diagnose_if'}}
86 _diagnose_if(1, "nop", "warning");
87 void errorWarnDiagnose2(void) _diagnose_if(1, "oh no", "error") // expected-note{{from 'diagnose_if'}}
88 _diagnose_if(1, "nop", "error");
89 void errorWarnDiagnose3(void) _diagnose_if(1, "nop", "warning")
90 _diagnose_if(1, "oh no", "error"); // expected-note{{from 'diagnose_if'}}
92 void errorWarnDiagnoseArg1(int a
) _diagnose_if(a
== 1, "oh no", "error") // expected-note{{from 'diagnose_if'}}
93 _diagnose_if(a
== 1, "nop", "warning");
94 void errorWarnDiagnoseArg2(int a
) _diagnose_if(a
== 1, "oh no", "error") // expected-note{{from 'diagnose_if'}}
95 _diagnose_if(a
== 1, "nop", "error");
96 void errorWarnDiagnoseArg3(int a
) _diagnose_if(a
== 1, "nop", "warning")
97 _diagnose_if(a
== 1, "oh no", "error"); // expected-note{{from 'diagnose_if'}}
99 void runErrorWarnDiagnose(void) {
100 errorWarnDiagnose1(); // expected-error{{oh no}}
101 errorWarnDiagnose2(); // expected-error{{oh no}}
102 errorWarnDiagnose3(); // expected-error{{oh no}}
104 errorWarnDiagnoseArg1(1); // expected-error{{oh no}}
105 errorWarnDiagnoseArg2(1); // expected-error{{oh no}}
106 errorWarnDiagnoseArg3(1); // expected-error{{oh no}}
109 void warnWarnDiagnose(void) _diagnose_if(1, "oh no!", "warning") _diagnose_if(1, "foo", "warning"); // expected-note 2{{from 'diagnose_if'}}
110 void runWarnWarnDiagnose(void) {
111 warnWarnDiagnose(); // expected-warning{{oh no!}} expected-warning{{foo}}
114 void declsStackErr1(int a
) _diagnose_if(a
& 1, "decl1", "error"); // expected-note 2{{from 'diagnose_if'}}
115 void declsStackErr1(int a
) _diagnose_if(a
& 2, "decl2", "error"); // expected-note{{from 'diagnose_if'}}
116 void declsStackErr2(void);
117 void declsStackErr2(void) _diagnose_if(1, "complaint", "error"); // expected-note{{from 'diagnose_if'}}
118 void declsStackErr3(void) _diagnose_if(1, "complaint", "error"); // expected-note{{from 'diagnose_if'}}
119 void declsStackErr3(void);
120 void runDeclsStackErr(void) {
122 declsStackErr1(1); // expected-error{{decl1}}
123 declsStackErr1(2); // expected-error{{decl2}}
124 declsStackErr1(3); // expected-error{{decl1}}
125 declsStackErr2(); // expected-error{{complaint}}
126 declsStackErr3(); // expected-error{{complaint}}
129 void declsStackWarn1(int a
) _diagnose_if(a
& 1, "decl1", "warning"); // expected-note 2{{from 'diagnose_if'}}
130 void declsStackWarn1(int a
) _diagnose_if(a
& 2, "decl2", "warning"); // expected-note 2{{from 'diagnose_if'}}
131 void declsStackWarn2(void);
132 void declsStackWarn2(void) _diagnose_if(1, "complaint", "warning"); // expected-note{{from 'diagnose_if'}}
133 void declsStackWarn3(void) _diagnose_if(1, "complaint", "warning"); // expected-note{{from 'diagnose_if'}}
134 void declsStackWarn3(void);
135 void runDeclsStackWarn(void) {
137 declsStackWarn1(1); // expected-warning{{decl1}}
138 declsStackWarn1(2); // expected-warning{{decl2}}
139 declsStackWarn1(3); // expected-warning{{decl1}} expected-warning{{decl2}}
140 declsStackWarn2(); // expected-warning{{complaint}}
141 declsStackWarn3(); // expected-warning{{complaint}}
144 void noMsg(int n
) _diagnose_if(n
, "", "warning"); // expected-note{{from 'diagnose_if'}}
145 void runNoMsg(void) {
146 noMsg(1); // expected-warning{{<no message provided>}}
149 void alwaysWarnWithArg(int a
) _diagnose_if(1 || a
, "alwaysWarn", "warning"); // expected-note{{from 'diagnose_if'}}
150 void runAlwaysWarnWithArg(int a
) {
151 alwaysWarnWithArg(a
); // expected-warning{{alwaysWarn}}
154 // Test that diagnose_if warnings generated in system headers are not ignored.
155 #include "Inputs/diagnose-if-warn-system-header.h"
157 // Bug: we would complain about `a` being undeclared if this was spelled
159 void underbarName(int a
) __attribute__((__diagnose_if__(a
, "", "warning")));
162 void constCharStar(const char *str
) __attribute__((__diagnose_if__(!str
[0], "empty string not allowed", "error"))); // expected-note {{from}}
163 void charStar(char *str
) __attribute__((__diagnose_if__(!str
[0], "empty string not allowed", "error"))); // expected-note {{from}}
164 void runConstCharStar(void) {
165 constCharStar("foo");
167 constCharStar(""); // expected-error {{empty string not allowed}}
168 charStar(""); // expected-error {{empty string not allowed}}