|  | // RUN: %clang_cc1 -fsyntax-only -Wself-assign -verify %s | 
|  |  | 
|  | void f() { | 
|  | int a = 42, b = 42; | 
|  | a = a; // expected-warning{{explicitly assigning}} | 
|  | b = b; // expected-warning{{explicitly assigning}} | 
|  | a = b; | 
|  | b = a = b; | 
|  | a = a = a; // expected-warning{{explicitly assigning}} | 
|  | a = b = b = a; | 
|  | } | 
|  |  | 
|  | // Dummy type. | 
|  | struct S {}; | 
|  |  | 
|  | void false_positives() { | 
|  | #define OP = | 
|  | #define LHS a | 
|  | #define RHS a | 
|  | int a = 42; | 
|  | // These shouldn't warn due to the use of the preprocessor. | 
|  | a OP a; | 
|  | LHS = a; | 
|  | a = RHS; | 
|  | LHS OP RHS; | 
|  | #undef OP | 
|  | #undef LHS | 
|  | #undef RHS | 
|  |  | 
|  | S s; | 
|  | s = s; // Not a builtin assignment operator, no warning. | 
|  |  | 
|  | // Volatile stores aren't side-effect free. | 
|  | volatile int vol_a; | 
|  | vol_a = vol_a; | 
|  | volatile int &vol_a_ref = vol_a; | 
|  | vol_a_ref = vol_a_ref; | 
|  | } | 
|  |  | 
|  | template <typename T> void g() { | 
|  | T a; | 
|  | a = a; // May or may not be a builtin assignment operator, no warning. | 
|  | } | 
|  | void instantiate() { | 
|  | g<int>(); | 
|  | g<S>(); | 
|  | } |