// 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; a &= a; // expected-warning{{explicitly assigning}} a |= a; // expected-warning{{explicitly assigning}} a ^= 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>(); }