[clang-tools-extra] [clang-tidy] Add performance-bool-bitwise-operation check (PR #142324)
Denis Mikhailov via cfe-commits
cfe-commits at lists.llvm.org
Sun Jun 15 15:18:48 PDT 2025
================
@@ -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
More information about the cfe-commits
mailing list