================ @@ -0,0 +1,403 @@ +// RUN: %check_clang_tidy %s performance-bool-bitwise-operation %t + +bool& normal() { + int a = 100, b = 200; + + a | b; + a & b; + a |= b; + a &= b; + + static bool st = false; + return st; +} + +bool bad() noexcept __attribute__((pure)) { + bool a = true, b = false; + a | b; + // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [performance-bool-bitwise-operation] + // CHECK-FIXES: a || b; + a & b; + // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '&&' for boolean values instead of bitwise operator '&' [performance-bool-bitwise-operation] + // CHECK-FIXES: a && b; + a |= b; + // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '||' for boolean variable 'a' instead of bitwise operator '|=' [performance-bool-bitwise-operation] + // CHECK-FIXES: a = a || b; + a &= b; + // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '&&' for boolean variable 'a' instead of bitwise operator '&=' [performance-bool-bitwise-operation] + // CHECK-FIXES: a = a && b; + + return true; +} + +bool global_1 = bad() | bad(); +// CHECK-MESSAGES: :[[@LINE-1]]:23: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [performance-bool-bitwise-operation] +// CHECK-FIXES: bool global_1 = bad() || bad(); +bool global_2 = bad() & bad(); +// CHECK-MESSAGES: :[[@LINE-1]]:23: warning: use logical operator '&&' for boolean values instead of bitwise operator '&' [performance-bool-bitwise-operation] +// CHECK-FIXES: bool global_2 = bad() && bad(); + +using Boolean = bool; + +bool bad_typedef() { + Boolean a = true, b = false; + a | b; + // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [performance-bool-bitwise-operation] + // CHECK-FIXES: a || b; + a & b; + // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '&&' for boolean values instead of bitwise operator '&' [performance-bool-bitwise-operation] + // CHECK-FIXES: a && b; + a |= b; + // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '||' for boolean variable 'a' instead of bitwise operator '|=' [performance-bool-bitwise-operation] + // CHECK-FIXES: a = a || b; + a &= b; + // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '&&' for boolean variable 'a' instead of bitwise operator '&=' [performance-bool-bitwise-operation] + // CHECK-FIXES: a = a && b; + return true; +} + +bool function_with_possible_side_effects(); + +void bad_side_effects() { + bool a = true, b = false; + + a | function_with_possible_side_effects(); + // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [performance-bool-bitwise-operation] + // CHECK-MESSAGES-NOT: :[[@LINE-2]]:{{.*}}: note: FIX-IT applied suggested code changes + + a & function_with_possible_side_effects(); + // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '&&' for boolean values instead of bitwise operator '&' [performance-bool-bitwise-operation] + // CHECK-MESSAGES-NOT: :[[@LINE-2]]:{{.*}}: note: FIX-IT applied suggested code changes + + function_with_possible_side_effects() | a; + // CHECK-MESSAGES: :[[@LINE-1]]:43: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [performance-bool-bitwise-operation] + // CHECK-FIXES: function_with_possible_side_effects() || a; + + function_with_possible_side_effects() & a; + // CHECK-MESSAGES: :[[@LINE-1]]:43: warning: use logical operator '&&' for boolean values instead of bitwise operator '&' [performance-bool-bitwise-operation] + // CHECK-FIXES: function_with_possible_side_effects() && a; + a |= function_with_possible_side_effects(); + // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '||' for boolean variable 'a' instead of bitwise operator '|=' [performance-bool-bitwise-operation] + // CHECK-MESSAGES-NOT: :[[@LINE-2]]:{{.*}}: note: FIX-IT applied suggested code changes + + a &= function_with_possible_side_effects(); + // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '&&' for boolean variable 'a' instead of bitwise operator '&=' [performance-bool-bitwise-operation] + // CHECK-MESSAGES-NOT: :[[@LINE-2]]:{{.*}}: note: FIX-IT applied suggested code changes + + // count of evaluation with side effect remains the same, so the fixit will be provided + bool c = true; + + a || function_with_possible_side_effects() | c; + // CHECK-MESSAGES: :[[@LINE-1]]:48: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [performance-bool-bitwise-operation] + // CHECK-FIXES: a || function_with_possible_side_effects() || c; + + function_with_possible_side_effects() || b | c; + // CHECK-MESSAGES: :[[@LINE-1]]:48: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [performance-bool-bitwise-operation] + // CHECK-FIXES: function_with_possible_side_effects() || b || c; + + a && function_with_possible_side_effects() & c; + // CHECK-MESSAGES: :[[@LINE-1]]:48: warning: use logical operator '&&' for boolean values instead of bitwise operator '&' [performance-bool-bitwise-operation] + // CHECK-FIXES: a && function_with_possible_side_effects() && c; + + function_with_possible_side_effects() && b & c; + // CHECK-MESSAGES: :[[@LINE-1]]:48: warning: use logical operator '&&' for boolean values instead of bitwise operator '&' [performance-bool-bitwise-operation] + // CHECK-FIXES: function_with_possible_side_effects() && b && c; + + // but here the count of evaluation migh be changed - no fix must be provided + + a &= function_with_possible_side_effects() && c; + // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '&&' for boolean variable 'a' instead of bitwise operator '&=' [performance-bool-bitwise-operation] + // CHECK-MESSAGES-NOT: :[[@LINE-2]]:{{.*}}: note: FIX-IT applied suggested code changes + + a &= b && function_with_possible_side_effects(); + // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '&&' for boolean variable 'a' instead of bitwise operator '&=' [performance-bool-bitwise-operation] + // CHECK-MESSAGES-NOT: :[[@LINE-2]]:{{.*}}: note: FIX-IT applied suggested code changes + + a |= function_with_possible_side_effects() || c; + // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '||' for boolean variable 'a' instead of bitwise operator '|=' [performance-bool-bitwise-operation] + // CHECK-MESSAGES-NOT: :[[@LINE-2]]:{{.*}}: note: FIX-IT applied suggested code changes + + a |= b || function_with_possible_side_effects(); + // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '||' for boolean variable 'a' instead of bitwise operator '|=' [performance-bool-bitwise-operation] + // CHECK-MESSAGES-NOT: :[[@LINE-2]]:{{.*}}: note: FIX-IT applied suggested code changes +} + +void bad_side_effects_volatile() { + bool a = true; + volatile bool b = false; + a | b; + // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [performance-bool-bitwise-operation] + // CHECK-MESSAGES-NOT: :[[@LINE-2]]:{{.*}}: note: FIX-IT applied suggested code changes + a & b; + // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '&&' for boolean values instead of bitwise operator '&' [performance-bool-bitwise-operation] + // CHECK-MESSAGES-NOT: :[[@LINE-2]]:{{.*}}: note: FIX-IT applied suggested code changes + + a |= b; + // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '||' for boolean variable 'a' instead of bitwise operator '|=' [performance-bool-bitwise-operation] + // CHECK-MESSAGES-NOT: :[[@LINE-2]]:{{.*}}: note: FIX-IT applied suggested code changes + a &= b; + // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '&&' for boolean variable 'a' instead of bitwise operator '&=' [performance-bool-bitwise-operation] + // CHECK-MESSAGES-NOT: :[[@LINE-2]]:{{.*}}: note: FIX-IT applied suggested code changes +} + +void bad_with_priors() { + bool a = false, b = true, c = true; + a && b | c; + // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [performance-bool-bitwise-operation] + // CHECK-FIXES: a && (b || c); + a && b & c; + // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: use logical operator '&&' for boolean values instead of bitwise operator '&' [performance-bool-bitwise-operation] + // CHECK-FIXES: a && b && c; + a || b & c; + // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: use logical operator '&&' for boolean values instead of bitwise operator '&' [performance-bool-bitwise-operation] + // CHECK-FIXES: a || b && c; + a || b | c; + // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [performance-bool-bitwise-operation] + // CHECK-FIXES: a || b || c; + b | c && a; + // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [performance-bool-bitwise-operation] + // CHECK-FIXES: (b || c) && a; + + bool q = (true && false | true) && (false | true && (false && true | false)); + // CHECK-MESSAGES: :[[@LINE-1]]:29: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [performance-bool-bitwise-operation] + // CHECK-MESSAGES: :[[@LINE-2]]:47: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [performance-bool-bitwise-operation] + // CHECK-MESSAGES: :[[@LINE-3]]:72: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [performance-bool-bitwise-operation] + // CHECK-FIXES: bool q = (true && (false || true)) && ((false || true) && (false && (true || false))); +} + +void bad_with_priors2() { + bool a = false, b = true, c = true; + a ^ b & c; + // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: use logical operator '&&' for boolean values instead of bitwise operator '&' [performance-bool-bitwise-operation] + // CHECK-FIXES: a ^ (b && c); + + // braces added in the first change + a | b & c; + // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [performance-bool-bitwise-operation] + // CHECK-MESSAGES: :[[@LINE-2]]:11: warning: use logical operator '&&' for boolean values instead of bitwise operator '&' [performance-bool-bitwise-operation] + // CHECK-FIXES: a || (b && c); + + b & c ^ a; + // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '&&' for boolean values instead of bitwise operator '&' [performance-bool-bitwise-operation] + // CHECK-FIXES: (b && c) ^ a; + + // braces added in the first change + b & c | a; + // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '&&' for boolean values instead of bitwise operator '&' [performance-bool-bitwise-operation] + // CHECK-MESSAGES: :[[@LINE-2]]:11: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [performance-bool-bitwise-operation] + // CHECK-FIXES: (b && c) || a; +} + +template<typename T> +T ident(T val) { return val; } + +// cases to check `hasAncestor` works as we expected: +void bad_has_ancestor() { + bool a = false, b = true, c = true; + bool d = false; + d ^ (a && b & c); + // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: use logical operator '&&' for boolean values instead of bitwise operator '&' [performance-bool-bitwise-operation] + // CHECK-FIXES: d ^ (a && b && c); + + a ^ ident(b & c || a); + // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: use logical operator '&&' for boolean values instead of bitwise operator '&' [performance-bool-bitwise-operation] + // CHECK-FIXES: a ^ ident(b && c || a); + + a | ident(a ? b & c : c); + // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [performance-bool-bitwise-operation] + // CHECK-MESSAGES: :[[@LINE-2]]:21: warning: use logical operator '&&' for boolean values instead of bitwise operator '&' [performance-bool-bitwise-operation] + // CHECK-FIXES: a | ident(a ? b && c : c); +} + +void bad_with_priors_already_braced() { + bool a = false, b = true, c = true; + a && (b | c); + // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [performance-bool-bitwise-operation] + // CHECK-FIXES: a && (b || c); + (b | c) && a; + // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [performance-bool-bitwise-operation] + // CHECK-FIXES: (b || c) && a; + + bool q = (true && (false | true)) && ((false | true) && (false && (true | false))); + // CHECK-MESSAGES: :[[@LINE-1]]:30: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [performance-bool-bitwise-operation] + // CHECK-MESSAGES: :[[@LINE-2]]:50: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [performance-bool-bitwise-operation] + // CHECK-MESSAGES: :[[@LINE-3]]:77: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [performance-bool-bitwise-operation] + // CHECK-FIXES: bool q = (true && (false || true)) && ((false || true) && (false && (true || false))); + + a ^ (b & c); + // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: use logical operator '&&' for boolean values instead of bitwise operator '&' [performance-bool-bitwise-operation] + // CHECK-FIXES: a ^ (b && c); + + a | (b & c); + // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [performance-bool-bitwise-operation] + // CHECK-MESSAGES: :[[@LINE-2]]:12: warning: use logical operator '&&' for boolean values instead of bitwise operator '&' [performance-bool-bitwise-operation] + // CHECK-FIXES: a || (b && c); + + (b & c) ^ a; + // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: use logical operator '&&' for boolean values instead of bitwise operator '&' [performance-bool-bitwise-operation] + // CHECK-FIXES: (b && c) ^ a; + + (b & c) | a; + // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: use logical operator '&&' for boolean values instead of bitwise operator '&' [performance-bool-bitwise-operation] + // CHECK-MESSAGES: :[[@LINE-2]]:13: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [performance-bool-bitwise-operation] + // CHECK-FIXES: (b && c) || a; +} + +void bad_with_priors_compound() { + bool a = false, b = true, c = true; + a &= b || c; + // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '&&' for boolean variable 'a' instead of bitwise operator '&=' [performance-bool-bitwise-operation] + // CHECK-FIXES: a = a && (b || c); + a |= b || c; + // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '||' for boolean variable 'a' instead of bitwise operator '|=' [performance-bool-bitwise-operation] + // CHECK-FIXES: a = a || b || c; + a &= b && c; + // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '&&' for boolean variable 'a' instead of bitwise operator '&=' [performance-bool-bitwise-operation] + // CHECK-FIXES: a = a && b && c; + a |= b && c; + // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '||' for boolean variable 'a' instead of bitwise operator '|=' [performance-bool-bitwise-operation] + // CHECK-FIXES: a = a || b && c; +} + +void bad_with_priors_compound_already_braced() { + bool a = false, b = true, c = true; + a &= (b || c); + // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '&&' for boolean variable 'a' instead of bitwise operator '&=' [performance-bool-bitwise-operation] + // CHECK-FIXES: a = a && (b || c); +} + +void bad_no_fixit() { + bool b = false; + normal() |= b; + // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: use logical operator '||' for boolean values instead of bitwise operator '|=' [performance-bool-bitwise-operation] + // CHECK-MESSAGES-NOT: :[[@LINE-2]]:{{.*}}: note: FIX-IT applied suggested code changes + normal() &= b; + // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: use logical operator '&&' for boolean values instead of bitwise operator '&=' [performance-bool-bitwise-operation] + // CHECK-MESSAGES-NOT: :[[@LINE-2]]:{{.*}}: note: FIX-IT applied suggested code changes +} + +#define MY_OR | +#define MY_AND & +#define MY_OR_ASSIGN |= +#define MY_AND_ASSIGN &= +#define MY_LOG_AND && + +#define CAT(a, b) a ## b +#define IDENT(a) a + +void bad_in_macro() { + bool a = true, b = false; + + // change operator - BAD + a MY_OR b; ---------------- denzor200 wrote:
`a MY_OR b;` - this might be correct fixit case in future versions, please change it to `IDENT(a |) b;` https://github.com/llvm/llvm-project/pull/142324 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits