340 lines · cpp
1// RUN: %clang_cc1 -fsyntax-only -Wcomma -std=c++11 -verify %s2// RUN: %clang_cc1 -fsyntax-only -Wcomma -std=c++11 -fdiagnostics-parseable-fixits %s 2>&1 | FileCheck %s3 4// RUN: %clang_cc1 -fsyntax-only -Wcomma -x c -std=c89 -verify %s5// RUN: %clang_cc1 -fsyntax-only -Wcomma -x c -std=c99 -verify %s6// RUN: %clang_cc1 -fsyntax-only -Wcomma -x c -std=c11 -verify %s7// RUN: %clang_cc1 -fsyntax-only -Wcomma -x c -std=c17 -verify %s8 9// int returning function10int return_four(void) { return 5; }11 12// Test builtin operators13void test_builtin(void) {14 int x = 0, y = 0;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) {}32}33 34// Test nested comma operators35void test_nested(void) {36 int x1, x2, x3;37 int y1, *y2 = 0, y3 = 5;38 39#if __STDC_VERSION >= 199901L40 for (int z1 = 5, z2 = 4, z3 = 3; x1 <4; ++x1) {}41#endif42}43 44// Confusing "," for "=="45void test_compare(void) {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}:")"51 52 if (return_four() == 5) {}53}54 55// Confusing "," for "+"56int test_plus(void) {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}:")"62 63 return return_four() + return_four();64}65 66// Be sure to look through parentheses67void test_parentheses(void) {68 int x, y;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}:")"74 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}:")"80}81 82void test_increment(void) {83 int x, y;84 ++x, ++y;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}:")"89}90 91// Check for comma operator in conditions.92void 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}:")"98 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}:")"104 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}:")"110 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}:")"116 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}:")"122 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}:")"128}129 130// Nested comma operator with fix-its.131void test_nested_fixits(void) {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}:")"141}142 143 144void void_func();145int int_func() { return 0; }146 147void void_function_comma(){148 void_func(), int_func(); // expected no -Wcomma because of the returning type `void` 149 // Reported by https://github.com/llvm/llvm-project/issues/57151150 // Descriptions about -Wcomma: https://reviews.llvm.org/D3976151}152 153typedef void Void;154Void typedef_func();155 156void whatever() {157 // We don't get confused about type aliases.158 typedef_func(), int_func();159 // Even function pointers don't confuse us.160 void (*fp)() = void_func;161 fp(), int_func();162}163 164#ifdef __cplusplus165class S2 {166public:167 void advance();168 169 S2 operator++();170 S2 operator++(int);171 S2 operator--();172 S2 operator--(int);173 S2 operator=(int);174 S2 operator*=(int);175 S2 operator/=(int);176 S2 operator%=(int);177 S2 operator+=(int);178 S2 operator-=(int);179 S2 operator<<=(int);180 S2 operator>>=(int);181 S2 operator&=(int);182 S2 operator|=(int);183 S2 operator^=(int);184};185 186// Test overloaded operators187void test_overloaded_operator() {188 S2 x;189 int y;190 for (; y < 10; x++, y++) {}191 for (; y < 10; ++x, y++) {}192 for (; y < 10; x++, ++y) {}193 for (; y < 10; ++x, ++y) {}194 for (; y < 10; x--, ++y) {}195 for (; y < 10; --x, ++y) {}196 for (; y < 10; x = 5, ++y) {}197 for (; y < 10; x *= 5, ++y) {}198 for (; y < 10; x /= 5, ++y) {}199 for (; y < 10; x %= 5, ++y) {}200 for (; y < 10; x += 5, ++y) {}201 for (; y < 10; x -= 5, ++y) {}202 for (; y < 10; x <<= 5, ++y) {}203 for (; y < 10; x >>= 5, ++y) {}204 for (; y < 10; x &= 5, ++y) {}205 for (; y < 10; x |= 5, ++y) {}206 for (; y < 10; x ^= 5, ++y) {}207}208 209class Stream {210 public:211 Stream& operator<<(int);212} cout;213 214// Confusing "," for "<<"215void test_stream() {216 cout << 5 << return_four();217 cout << 5, return_four();218 // expected-warning@-1{{comma operator}}219 // expected-note@-2{{cast expression to void}}220 // CHECK: fix-it:{{.*}}:{[[@LINE-3]]:3-[[@LINE-3]]:3}:"static_cast<void>("221 // CHECK: fix-it:{{.*}}:{[[@LINE-4]]:12-[[@LINE-4]]:12}:")"222}223 224void Concat(int);225void Concat(int, int);226 227// Testing extra parentheses in function call228void test_overloaded_function() {229 Concat((return_four() , 5));230 // expected-warning@-1{{comma operator}}231 // expected-note@-2{{cast expression to void}}232 // CHECK: fix-it:{{.*}}:{[[@LINE-3]]:11-[[@LINE-3]]:11}:"static_cast<void>("233 // CHECK: fix-it:{{.*}}:{[[@LINE-4]]:24-[[@LINE-4]]:24}:")"234 235 Concat(return_four() , 5);236}237 238bool DoStuff();239class S9 {240public:241 bool Advance();242 bool More();243};244 245// Ignore comma operator in for-loop initializations and increments.246void test_for_loop() {247 int x, y;248 for (x = 0, y = 5; x < y; ++x) {}249 for (x = 0; x < 10; DoStuff(), ++x) {}250 for (S9 s; s.More(); s.Advance(), ++x) {}251}252 253// Ignore comma operator in templates.254namespace test_template {255template <bool T>256struct B { static const bool value = T; };257 258typedef B<true> true_type;259typedef B<false> false_type;260 261template <bool...>262struct bool_seq;263 264template <typename... xs>265class Foo {266 typedef bool_seq<((void)xs::value, true)...> all_true;267 typedef bool_seq<((void)xs::value, false)...> all_false;268 typedef bool_seq<xs::value...> seq;269};270 271const auto X = Foo<true_type>();272}273 274namespace test_mutex {275class Mutex {276 public:277 Mutex();278 ~Mutex();279};280class MutexLock {281public:282 MutexLock(Mutex &);283 MutexLock();284 ~MutexLock();285};286class BuiltinMutex {287 Mutex M;288};289Mutex StatusMutex;290bool Status;291 292bool get_status() {293 return (MutexLock(StatusMutex), Status);294 // expected-warning@-1{{comma operator}}295 // expected-note@-2{{cast expression to void}}296 // CHECK: fix-it:{{.*}}:{[[@LINE-3]]:11-[[@LINE-3]]:11}:"static_cast<void>("297 // CHECK: fix-it:{{.*}}:{[[@LINE-4]]:33-[[@LINE-4]]:33}:")"298 return (MutexLock(), Status);299 // expected-warning@-1{{comma operator}}300 // expected-note@-2{{cast expression to void}}301 // CHECK: fix-it:{{.*}}:{[[@LINE-3]]:11-[[@LINE-3]]:11}:"static_cast<void>("302 // CHECK: fix-it:{{.*}}:{[[@LINE-4]]:22-[[@LINE-4]]:22}:")"303 return (BuiltinMutex(), Status);304 // expected-warning@-1{{comma operator}}305 // expected-note@-2{{cast expression to void}}306 // CHECK: fix-it:{{.*}}:{[[@LINE-3]]:11-[[@LINE-3]]:11}:"static_cast<void>("307 // CHECK: fix-it:{{.*}}:{[[@LINE-4]]:25-[[@LINE-4]]:25}:")"308}309}310 311// PR39375 - test cast to void to silence warnings312template <typename T>313void test_dependent_cast() {314 (void)42, 0;315 static_cast<void>(42), 0;316 317 (void)T{}, 0;318 static_cast<void>(T{}), 0;319}320 321namespace {322 323// issue #57151324 325struct S {326 void mem() {}327};328 329void whatever() {330 struct S s;331 // Member function calls also work as expected.332 s.mem(), int_func();333 // As do lambda calls.334 []() { return; }(), int_func();335}336 337} // namespace338 339#endif // ifdef __cplusplus340