diff options
Diffstat (limited to 'clang/test/SemaCXX/warn-comma-operator.cpp')
-rw-r--r-- | clang/test/SemaCXX/warn-comma-operator.cpp | 278 |
1 files changed, 278 insertions, 0 deletions
diff --git a/clang/test/SemaCXX/warn-comma-operator.cpp b/clang/test/SemaCXX/warn-comma-operator.cpp new file mode 100644 index 00000000000..3192f688f1b --- /dev/null +++ b/clang/test/SemaCXX/warn-comma-operator.cpp @@ -0,0 +1,278 @@ +// RUN: %clang_cc1 -fsyntax-only -Wcomma -std=c++11 -verify %s +// RUN: %clang_cc1 -fsyntax-only -Wcomma -std=c++11 -fdiagnostics-parseable-fixits %s 2>&1 | FileCheck %s + +// Test builtin operators +void test1() { + int x = 0, y = 0; + for (; y < 10; x++, y++) {} + for (; y < 10; ++x, y++) {} + for (; y < 10; x++, ++y) {} + for (; y < 10; ++x, ++y) {} + for (; y < 10; x--, ++y) {} + for (; y < 10; --x, ++y) {} + for (; y < 10; x = 5, ++y) {} + for (; y < 10; x *= 5, ++y) {} + for (; y < 10; x /= 5, ++y) {} + for (; y < 10; x %= 5, ++y) {} + for (; y < 10; x += 5, ++y) {} + for (; y < 10; x -= 5, ++y) {} + for (; y < 10; x <<= 5, ++y) {} + for (; y < 10; x >>= 5, ++y) {} + for (; y < 10; x &= 5, ++y) {} + for (; y < 10; x |= 5, ++y) {} + for (; y < 10; x ^= 5, ++y) {} +} + +class S2 { +public: + void advance(); + + S2 operator++(); + S2 operator++(int); + S2 operator--(); + S2 operator--(int); + S2 operator=(int); + S2 operator*=(int); + S2 operator/=(int); + S2 operator%=(int); + S2 operator+=(int); + S2 operator-=(int); + S2 operator<<=(int); + S2 operator>>=(int); + S2 operator&=(int); + S2 operator|=(int); + S2 operator^=(int); +}; + +// Test overloaded operators +void test2() { + S2 x; + int y; + for (; y < 10; x++, y++) {} + for (; y < 10; ++x, y++) {} + for (; y < 10; x++, ++y) {} + for (; y < 10; ++x, ++y) {} + for (; y < 10; x--, ++y) {} + for (; y < 10; --x, ++y) {} + for (; y < 10; x = 5, ++y) {} + for (; y < 10; x *= 5, ++y) {} + for (; y < 10; x /= 5, ++y) {} + for (; y < 10; x %= 5, ++y) {} + for (; y < 10; x += 5, ++y) {} + for (; y < 10; x -= 5, ++y) {} + for (; y < 10; x <<= 5, ++y) {} + for (; y < 10; x >>= 5, ++y) {} + for (; y < 10; x &= 5, ++y) {} + for (; y < 10; x |= 5, ++y) {} + for (; y < 10; x ^= 5, ++y) {} +} + +// Test nested comma operators +void test3() { + int x1, x2, x3; + int y1, *y2 = 0, y3 = 5; + for (int z1 = 5, z2 = 4, z3 = 3; x1 <4; ++x1) {} +} + +class Stream { + public: + Stream& operator<<(int); +} cout; + +int return_four() { return 5; } + +// Confusing "," for "<<" +void test4() { + cout << 5 << return_four(); + cout << 5, return_four(); + // expected-warning@-1{{comma operator}} + // expected-note@-2{{cast expression to void}} + // CHECK: fix-it:{{.*}}:{[[@LINE-3]]:3-[[@LINE-3]]:3}:"static_cast<void>(" + // CHECK: fix-it:{{.*}}:{[[@LINE-4]]:12-[[@LINE-4]]:12}:")" +} + +// Confusing "," for "==" +void test5() { + if (return_four(), 5) {} + // expected-warning@-1{{comma operator}} + // expected-note@-2{{cast expression to void}} + // CHECK: fix-it:{{.*}}:{[[@LINE-3]]:7-[[@LINE-3]]:7}:"static_cast<void>(" + // CHECK: fix-it:{{.*}}:{[[@LINE-4]]:20-[[@LINE-4]]:20}:")" + + if (return_four() == 5) {} +} + +// Confusing "," for "+" +int test6() { + return return_four(), return_four(); + // expected-warning@-1{{comma operator}} + // expected-note@-2{{cast expression to void}} + // CHECK: fix-it:{{.*}}:{[[@LINE-3]]:10-[[@LINE-3]]:10}:"static_cast<void>(" + // CHECK: fix-it:{{.*}}:{[[@LINE-4]]:23-[[@LINE-4]]:23}:")" + + return return_four() + return_four(); +} + +void Concat(int); +void Concat(int, int); + +// Testing extra parentheses in function call +void test7() { + Concat((return_four() , 5)); + // expected-warning@-1{{comma operator}} + // expected-note@-2{{cast expression to void}} + // CHECK: fix-it:{{.*}}:{[[@LINE-3]]:11-[[@LINE-3]]:11}:"static_cast<void>(" + // CHECK: fix-it:{{.*}}:{[[@LINE-4]]:24-[[@LINE-4]]:24}:")" + + Concat(return_four() , 5); +} + +// Be sure to look through parentheses +void test8() { + int x, y; + for (x = 0; return_four(), x;) {} + // expected-warning@-1{{comma operator}} + // expected-note@-2{{cast expression to void}} + // CHECK: fix-it:{{.*}}:{[[@LINE-3]]:15-[[@LINE-3]]:15}:"static_cast<void>(" + // CHECK: fix-it:{{.*}}:{[[@LINE-4]]:28-[[@LINE-4]]:28}:")" + + for (x = 0; (return_four()), (x) ;) {} + // expected-warning@-1{{comma operator}} + // expected-note@-2{{cast expression to void}} + // CHECK: fix-it:{{.*}}:{[[@LINE-3]]:15-[[@LINE-3]]:15}:"static_cast<void>(" + // CHECK: fix-it:{{.*}}:{[[@LINE-4]]:30-[[@LINE-4]]:30}:")" +} + +bool DoStuff(); +class S9 { +public: + bool Advance(); + bool More(); +}; + +// Ignore comma operator in for-loop initializations and increments. +void test9() { + int x, y; + for (x = 0, y = 5; x < y; ++x) {} + for (x = 0; x < 10; DoStuff(), ++x) {} + for (S9 s; s.More(); s.Advance(), ++x) {} +} + +void test10() { + int x, y; + ++x, ++y; + // expected-warning@-1{{comma operator}} + // expected-note@-2{{cast expression to void}} + // CHECK: fix-it:{{.*}}:{[[@LINE-3]]:3-[[@LINE-3]]:3}:"static_cast<void>(" + // CHECK: fix-it:{{.*}}:{[[@LINE-4]]:6-[[@LINE-4]]:6}:")" +} + +// Ignore comma operator in templates. +namespace test11 { +template <bool T> +struct B { static const bool value = T; }; + +typedef B<true> true_type; +typedef B<false> false_type; + +template <bool...> +struct bool_seq; + +template <typename... xs> +class Foo { + typedef bool_seq<(xs::value, true)...> all_true; + typedef bool_seq<(xs::value, false)...> all_false; + typedef bool_seq<xs::value...> seq; +}; + +const auto X = Foo<true_type>(); +} + +namespace test12 { +class Mutex { + public: + Mutex(); + ~Mutex(); +}; +class MutexLock { +public: + MutexLock(Mutex &); + MutexLock(); + ~MutexLock(); +}; +class BuiltinMutex { + Mutex M; +}; +Mutex StatusMutex; +bool Status; + +bool get_status() { + return (MutexLock(StatusMutex), Status); + // expected-warning@-1{{comma operator}} + // expected-note@-2{{cast expression to void}} + // CHECK: fix-it:{{.*}}:{[[@LINE-3]]:11-[[@LINE-3]]:11}:"static_cast<void>(" + // CHECK: fix-it:{{.*}}:{[[@LINE-4]]:33-[[@LINE-4]]:33}:")" + return (MutexLock(), Status); + // expected-warning@-1{{comma operator}} + // expected-note@-2{{cast expression to void}} + // CHECK: fix-it:{{.*}}:{[[@LINE-3]]:11-[[@LINE-3]]:11}:"static_cast<void>(" + // CHECK: fix-it:{{.*}}:{[[@LINE-4]]:22-[[@LINE-4]]:22}:")" + return (BuiltinMutex(), Status); + // expected-warning@-1{{comma operator}} + // expected-note@-2{{cast expression to void}} + // CHECK: fix-it:{{.*}}:{[[@LINE-3]]:11-[[@LINE-3]]:11}:"static_cast<void>(" + // CHECK: fix-it:{{.*}}:{[[@LINE-4]]:25-[[@LINE-4]]:25}:")" +} +} + +// Check for comma operator in conditions. +void test13(int x) { + x = (return_four(), x); + // expected-warning@-1{{comma operator}} + // expected-note@-2{{cast expression to void}} + // CHECK: fix-it:{{.*}}:{[[@LINE-3]]:8-[[@LINE-3]]:8}:"static_cast<void>(" + // CHECK: fix-it:{{.*}}:{[[@LINE-4]]:21-[[@LINE-4]]:21}:")" + + int y = (return_four(), x); + // expected-warning@-1{{comma operator}} + // expected-note@-2{{cast expression to void}} + // CHECK: fix-it:{{.*}}:{[[@LINE-3]]:12-[[@LINE-3]]:12}:"static_cast<void>(" + // CHECK: fix-it:{{.*}}:{[[@LINE-4]]:25-[[@LINE-4]]:25}:")" + + for (; return_four(), x;) {} + // expected-warning@-1{{comma operator}} + // expected-note@-2{{cast expression to void}} + // CHECK: fix-it:{{.*}}:{[[@LINE-3]]:10-[[@LINE-3]]:10}:"static_cast<void>(" + // CHECK: fix-it:{{.*}}:{[[@LINE-4]]:23-[[@LINE-4]]:23}:")" + + while (return_four(), x) {} + // expected-warning@-1{{comma operator}} + // expected-note@-2{{cast expression to void}} + // CHECK: fix-it:{{.*}}:{[[@LINE-3]]:10-[[@LINE-3]]:10}:"static_cast<void>(" + // CHECK: fix-it:{{.*}}:{[[@LINE-4]]:23-[[@LINE-4]]:23}:")" + + if (return_four(), x) {} + // expected-warning@-1{{comma operator}} + // expected-note@-2{{cast expression to void}} + // CHECK: fix-it:{{.*}}:{[[@LINE-3]]:7-[[@LINE-3]]:7}:"static_cast<void>(" + // CHECK: fix-it:{{.*}}:{[[@LINE-4]]:20-[[@LINE-4]]:20}:")" + + do { } while (return_four(), x); + // expected-warning@-1{{comma operator}} + // expected-note@-2{{cast expression to void}} + // CHECK: fix-it:{{.*}}:{[[@LINE-3]]:17-[[@LINE-3]]:17}:"static_cast<void>(" + // CHECK: fix-it:{{.*}}:{[[@LINE-4]]:30-[[@LINE-4]]:30}:")" +} + +// Nested comma operator with fix-its. +void test14() { + return_four(), return_four(), return_four(), return_four(); + // expected-warning@-1 3{{comma operator}} + // expected-note@-2 3{{cast expression to void}} + // CHECK: fix-it:{{.*}}:{[[@LINE-3]]:3-[[@LINE-3]]:3}:"static_cast<void>(" + // CHECK: fix-it:{{.*}}:{[[@LINE-4]]:16-[[@LINE-4]]:16}:")" + // CHECK: fix-it:{{.*}}:{[[@LINE-5]]:18-[[@LINE-5]]:18}:"static_cast<void>(" + // CHECK: fix-it:{{.*}}:{[[@LINE-6]]:31-[[@LINE-6]]:31}:")" + // CHECK: fix-it:{{.*}}:{[[@LINE-7]]:33-[[@LINE-7]]:33}:"static_cast<void>(" + // CHECK: fix-it:{{.*}}:{[[@LINE-8]]:46-[[@LINE-8]]:46}:")" +} |