1 // RUN: %clang_cc1 -fsyntax-only -Wcomma -std=c++11 -verify %s
2 // RUN: %clang_cc1 -fsyntax-only -Wcomma -std=c++11 -fdiagnostics-parseable-fixits %s 2>&1 | FileCheck %s
4 // RUN: %clang_cc1 -fsyntax-only -Wcomma -x c -std=c89 -verify %s
5 // RUN: %clang_cc1 -fsyntax-only -Wcomma -x c -std=c99 -verify %s
6 // RUN: %clang_cc1 -fsyntax-only -Wcomma -x c -std=c11 -verify %s
7 // RUN: %clang_cc1 -fsyntax-only -Wcomma -x c -std=c17 -verify %s
9 // int returning function
10 int return_four() { return 5; }
12 // Test builtin operators
15 for (; y
< 10; x
++, y
++) {}
16 for (; y
< 10; ++x
, y
++) {}
17 for (; y
< 10; x
++, ++y
) {}
18 for (; y
< 10; ++x
, ++y
) {}
19 for (; y
< 10; x
--, ++y
) {}
20 for (; y
< 10; --x
, ++y
) {}
21 for (; y
< 10; x
= 5, ++y
) {}
22 for (; y
< 10; x
*= 5, ++y
) {}
23 for (; y
< 10; x
/= 5, ++y
) {}
24 for (; y
< 10; x
%= 5, ++y
) {}
25 for (; y
< 10; x
+= 5, ++y
) {}
26 for (; y
< 10; x
-= 5, ++y
) {}
27 for (; y
< 10; x
<<= 5, ++y
) {}
28 for (; y
< 10; x
>>= 5, ++y
) {}
29 for (; y
< 10; x
&= 5, ++y
) {}
30 for (; y
< 10; x
|= 5, ++y
) {}
31 for (; y
< 10; x
^= 5, ++y
) {}
34 // Test nested comma operators
37 int y1
, *y2
= 0, y3
= 5;
39 #if __STDC_VERSION >= 199901L
40 for (int z1
= 5, z2
= 4, z3
= 3; x1
<4; ++x1
) {}
44 // Confusing "," for "=="
46 if (return_four(), 5) {}
47 // expected-warning@-1{{comma operator}}
48 // expected-note@-2{{cast expression to void}}
49 // CHECK: fix-it:{{.*}}:{[[@LINE-3]]:7-[[@LINE-3]]:7}:"static_cast<void>("
50 // CHECK: fix-it:{{.*}}:{[[@LINE-4]]:20-[[@LINE-4]]:20}:")"
52 if (return_four() == 5) {}
55 // Confusing "," for "+"
57 return return_four(), return_four();
58 // expected-warning@-1{{comma operator}}
59 // expected-note@-2{{cast expression to void}}
60 // CHECK: fix-it:{{.*}}:{[[@LINE-3]]:10-[[@LINE-3]]:10}:"static_cast<void>("
61 // CHECK: fix-it:{{.*}}:{[[@LINE-4]]:23-[[@LINE-4]]:23}:")"
63 return return_four() + return_four();
66 // Be sure to look through parentheses
67 void test_parentheses() {
69 for (x
= 0; return_four(), x
;) {}
70 // expected-warning@-1{{comma operator}}
71 // expected-note@-2{{cast expression to void}}
72 // CHECK: fix-it:{{.*}}:{[[@LINE-3]]:15-[[@LINE-3]]:15}:"static_cast<void>("
73 // CHECK: fix-it:{{.*}}:{[[@LINE-4]]:28-[[@LINE-4]]:28}:")"
75 for (x
= 0; (return_four()), (x
) ;) {}
76 // expected-warning@-1{{comma operator}}
77 // expected-note@-2{{cast expression to void}}
78 // CHECK: fix-it:{{.*}}:{[[@LINE-3]]:15-[[@LINE-3]]:15}:"static_cast<void>("
79 // CHECK: fix-it:{{.*}}:{[[@LINE-4]]:30-[[@LINE-4]]:30}:")"
82 void test_increment() {
85 // expected-warning@-1{{comma operator}}
86 // expected-note@-2{{cast expression to void}}
87 // CHECK: fix-it:{{.*}}:{[[@LINE-3]]:3-[[@LINE-3]]:3}:"static_cast<void>("
88 // CHECK: fix-it:{{.*}}:{[[@LINE-4]]:6-[[@LINE-4]]:6}:")"
91 // Check for comma operator in conditions.
92 void test_conditions(int x
) {
93 x
= (return_four(), x
);
94 // expected-warning@-1{{comma operator}}
95 // expected-note@-2{{cast expression to void}}
96 // CHECK: fix-it:{{.*}}:{[[@LINE-3]]:8-[[@LINE-3]]:8}:"static_cast<void>("
97 // CHECK: fix-it:{{.*}}:{[[@LINE-4]]:21-[[@LINE-4]]:21}:")"
99 int y
= (return_four(), x
);
100 // expected-warning@-1{{comma operator}}
101 // expected-note@-2{{cast expression to void}}
102 // CHECK: fix-it:{{.*}}:{[[@LINE-3]]:12-[[@LINE-3]]:12}:"static_cast<void>("
103 // CHECK: fix-it:{{.*}}:{[[@LINE-4]]:25-[[@LINE-4]]:25}:")"
105 for (; return_four(), x
;) {}
106 // expected-warning@-1{{comma operator}}
107 // expected-note@-2{{cast expression to void}}
108 // CHECK: fix-it:{{.*}}:{[[@LINE-3]]:10-[[@LINE-3]]:10}:"static_cast<void>("
109 // CHECK: fix-it:{{.*}}:{[[@LINE-4]]:23-[[@LINE-4]]:23}:")"
111 while (return_four(), x
) {}
112 // expected-warning@-1{{comma operator}}
113 // expected-note@-2{{cast expression to void}}
114 // CHECK: fix-it:{{.*}}:{[[@LINE-3]]:10-[[@LINE-3]]:10}:"static_cast<void>("
115 // CHECK: fix-it:{{.*}}:{[[@LINE-4]]:23-[[@LINE-4]]:23}:")"
117 if (return_four(), x
) {}
118 // expected-warning@-1{{comma operator}}
119 // expected-note@-2{{cast expression to void}}
120 // CHECK: fix-it:{{.*}}:{[[@LINE-3]]:7-[[@LINE-3]]:7}:"static_cast<void>("
121 // CHECK: fix-it:{{.*}}:{[[@LINE-4]]:20-[[@LINE-4]]:20}:")"
123 do { } while (return_four(), x
);
124 // expected-warning@-1{{comma operator}}
125 // expected-note@-2{{cast expression to void}}
126 // CHECK: fix-it:{{.*}}:{[[@LINE-3]]:17-[[@LINE-3]]:17}:"static_cast<void>("
127 // CHECK: fix-it:{{.*}}:{[[@LINE-4]]:30-[[@LINE-4]]:30}:")"
130 // Nested comma operator with fix-its.
131 void test_nested_fixits() {
132 return_four(), return_four(), return_four(), return_four();
133 // expected-warning@-1 3{{comma operator}}
134 // expected-note@-2 3{{cast expression to void}}
135 // CHECK: fix-it:{{.*}}:{[[@LINE-3]]:3-[[@LINE-3]]:3}:"static_cast<void>("
136 // CHECK: fix-it:{{.*}}:{[[@LINE-4]]:16-[[@LINE-4]]:16}:")"
137 // CHECK: fix-it:{{.*}}:{[[@LINE-5]]:18-[[@LINE-5]]:18}:"static_cast<void>("
138 // CHECK: fix-it:{{.*}}:{[[@LINE-6]]:31-[[@LINE-6]]:31}:")"
139 // CHECK: fix-it:{{.*}}:{[[@LINE-7]]:33-[[@LINE-7]]:33}:"static_cast<void>("
140 // CHECK: fix-it:{{.*}}:{[[@LINE-8]]:46-[[@LINE-8]]:46}:")"
165 // Test overloaded operators
166 void test_overloaded_operator() {
169 for (; y
< 10; x
++, y
++) {}
170 for (; y
< 10; ++x
, y
++) {}
171 for (; y
< 10; x
++, ++y
) {}
172 for (; y
< 10; ++x
, ++y
) {}
173 for (; y
< 10; x
--, ++y
) {}
174 for (; y
< 10; --x
, ++y
) {}
175 for (; y
< 10; x
= 5, ++y
) {}
176 for (; y
< 10; x
*= 5, ++y
) {}
177 for (; y
< 10; x
/= 5, ++y
) {}
178 for (; y
< 10; x
%= 5, ++y
) {}
179 for (; y
< 10; x
+= 5, ++y
) {}
180 for (; y
< 10; x
-= 5, ++y
) {}
181 for (; y
< 10; x
<<= 5, ++y
) {}
182 for (; y
< 10; x
>>= 5, ++y
) {}
183 for (; y
< 10; x
&= 5, ++y
) {}
184 for (; y
< 10; x
|= 5, ++y
) {}
185 for (; y
< 10; x
^= 5, ++y
) {}
190 Stream
& operator<<(int);
193 // Confusing "," for "<<"
195 cout
<< 5 << return_four();
196 cout
<< 5, return_four();
197 // expected-warning@-1{{comma operator}}
198 // expected-note@-2{{cast expression to void}}
199 // CHECK: fix-it:{{.*}}:{[[@LINE-3]]:3-[[@LINE-3]]:3}:"static_cast<void>("
200 // CHECK: fix-it:{{.*}}:{[[@LINE-4]]:12-[[@LINE-4]]:12}:")"
204 void Concat(int, int);
206 // Testing extra parentheses in function call
207 void test_overloaded_function() {
208 Concat((return_four() , 5));
209 // expected-warning@-1{{comma operator}}
210 // expected-note@-2{{cast expression to void}}
211 // CHECK: fix-it:{{.*}}:{[[@LINE-3]]:11-[[@LINE-3]]:11}:"static_cast<void>("
212 // CHECK: fix-it:{{.*}}:{[[@LINE-4]]:24-[[@LINE-4]]:24}:")"
214 Concat(return_four() , 5);
224 // Ignore comma operator in for-loop initializations and increments.
225 void test_for_loop() {
227 for (x
= 0, y
= 5; x
< y
; ++x
) {}
228 for (x
= 0; x
< 10; DoStuff(), ++x
) {}
229 for (S9 s
; s
.More(); s
.Advance(), ++x
) {}
232 // Ignore comma operator in templates.
233 namespace test_template
{
235 struct B
{ static const bool value
= T
; };
237 typedef B
<true> true_type
;
238 typedef B
<false> false_type
;
243 template <typename
... xs
>
245 typedef bool_seq
<((void)xs::value
, true)...> all_true
;
246 typedef bool_seq
<((void)xs::value
, false)...> all_false
;
247 typedef bool_seq
<xs::value
...> seq
;
250 const auto X
= Foo
<true_type
>();
253 namespace test_mutex
{
272 return (MutexLock(StatusMutex
), Status
);
273 // expected-warning@-1{{comma operator}}
274 // expected-note@-2{{cast expression to void}}
275 // CHECK: fix-it:{{.*}}:{[[@LINE-3]]:11-[[@LINE-3]]:11}:"static_cast<void>("
276 // CHECK: fix-it:{{.*}}:{[[@LINE-4]]:33-[[@LINE-4]]:33}:")"
277 return (MutexLock(), Status
);
278 // expected-warning@-1{{comma operator}}
279 // expected-note@-2{{cast expression to void}}
280 // CHECK: fix-it:{{.*}}:{[[@LINE-3]]:11-[[@LINE-3]]:11}:"static_cast<void>("
281 // CHECK: fix-it:{{.*}}:{[[@LINE-4]]:22-[[@LINE-4]]:22}:")"
282 return (BuiltinMutex(), Status
);
283 // expected-warning@-1{{comma operator}}
284 // expected-note@-2{{cast expression to void}}
285 // CHECK: fix-it:{{.*}}:{[[@LINE-3]]:11-[[@LINE-3]]:11}:"static_cast<void>("
286 // CHECK: fix-it:{{.*}}:{[[@LINE-4]]:25-[[@LINE-4]]:25}:")"
290 // PR39375 - test cast to void to silence warnings
291 template <typename T
>
292 void test_dependent_cast() {
294 static_cast<void>(42), 0;
297 static_cast<void>(T
{}), 0;
299 #endif // ifdef __cplusplus