279 lines
		
	
	
		
			8.2 KiB
		
	
	
	
		
			C++
		
	
	
	
			
		
		
	
	
			279 lines
		
	
	
		
			8.2 KiB
		
	
	
	
		
			C++
		
	
	
	
| // 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}:")"
 | |
| }
 |