[clang-tools-extra] [clang-tidy] Add misc-bool-bitwise-operation check (PR #167552)
Denis Mikhailov via cfe-commits
cfe-commits at lists.llvm.org
Fri Nov 21 13:15:28 PST 2025
https://github.com/denzor200 updated https://github.com/llvm/llvm-project/pull/167552
>From 710b7b4de1fdef8f4b159d5cc3503f151e8ecbfc Mon Sep 17 00:00:00 2001
From: Denis Mikhailov <denismikhaylov38 at gmail.com>
Date: Tue, 21 Oct 2025 19:52:57 +0300
Subject: [PATCH 01/28] Stock files were taken
---
.../misc/BoolBitwiseOperationCheck.cpp | 181 ++++++++
.../misc/BoolBitwiseOperationCheck.h | 42 ++
.../clang-tidy/misc/CMakeLists.txt | 1 +
.../clang-tidy/misc/MiscTidyModule.cpp | 3 +
clang-tools-extra/docs/ReleaseNotes.rst | 7 +
.../docs/clang-tidy/checks/list.rst | 11 +-
.../checks/misc/bool-bitwise-operation.rst | 62 +++
...-operation-change-possible-side-effect.cpp | 82 ++++
.../bool-bitwise-operation-ignore-macros.cpp | 53 +++
.../bool-bitwise-operation-nontraditional.cpp | 399 ++++++++++++++++++
.../checkers/misc/bool-bitwise-operation.c | 26 ++
.../checkers/misc/bool-bitwise-operation.cpp | 399 ++++++++++++++++++
12 files changed, 1261 insertions(+), 5 deletions(-)
create mode 100644 clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.cpp
create mode 100644 clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.h
create mode 100644 clang-tools-extra/docs/clang-tidy/checks/misc/bool-bitwise-operation.rst
create mode 100644 clang-tools-extra/test/clang-tidy/checkers/misc/bool-bitwise-operation-change-possible-side-effect.cpp
create mode 100644 clang-tools-extra/test/clang-tidy/checkers/misc/bool-bitwise-operation-ignore-macros.cpp
create mode 100644 clang-tools-extra/test/clang-tidy/checkers/misc/bool-bitwise-operation-nontraditional.cpp
create mode 100644 clang-tools-extra/test/clang-tidy/checkers/misc/bool-bitwise-operation.c
create mode 100644 clang-tools-extra/test/clang-tidy/checkers/misc/bool-bitwise-operation.cpp
diff --git a/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.cpp b/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.cpp
new file mode 100644
index 0000000000000..f37e1482c4a7d
--- /dev/null
+++ b/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.cpp
@@ -0,0 +1,181 @@
+//===--- BoolBitwiseOperationCheck.cpp - clang-tidy -----------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "BoolBitwiseOperationCheck.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/Lex/Lexer.h"
+#include <array>
+#include <optional>
+#include <utility>
+
+using namespace clang::ast_matchers;
+
+namespace clang::tidy::misc {
+
+static const NamedDecl *
+getLHSNamedDeclIfCompoundAssign(const BinaryOperator *BO) {
+ if (BO->isCompoundAssignmentOp()) {
+ const auto *DeclRefLHS =
+ dyn_cast<DeclRefExpr>(BO->getLHS()->IgnoreImpCasts());
+ return DeclRefLHS ? DeclRefLHS->getDecl() : nullptr;
+ }
+ return nullptr;
+}
+
+constexpr std::array<std::pair<llvm::StringRef, llvm::StringRef>, 8U>
+ OperatorsTransformation{{{"|", "||"},
+ {"|=", "||"},
+ {"&", "&&"},
+ {"&=", "&&"},
+ {"bitand", "and"},
+ {"and_eq", "and"},
+ {"bitor", "or"},
+ {"or_eq", "or"}}};
+
+static llvm::StringRef translate(llvm::StringRef Value) {
+ for (const auto &[Bitwise, Logical] : OperatorsTransformation) {
+ if (Value == Bitwise)
+ return Logical;
+ }
+
+ return {};
+}
+
+BoolBitwiseOperationCheck::BoolBitwiseOperationCheck(StringRef Name,
+ ClangTidyContext *Context)
+ : ClangTidyCheck(Name, Context),
+ StrictMode(Options.get("StrictMode", false)),
+ IgnoreMacros(Options.get("IgnoreMacros", false)) {}
+
+void BoolBitwiseOperationCheck::storeOptions(
+ ClangTidyOptions::OptionMap &Opts) {
+ Options.store(Opts, "StrictMode", StrictMode);
+ Options.store(Opts, "IgnoreMacros", IgnoreMacros);
+}
+
+void BoolBitwiseOperationCheck::registerMatchers(MatchFinder *Finder) {
+ Finder->addMatcher(
+ binaryOperator(
+ unless(isExpansionInSystemHeader()),
+ hasAnyOperatorName("|", "&", "|=", "&="),
+ hasEitherOperand(expr(hasType(booleanType()))),
+ optionally(hasParent( // to simple implement transformations like
+ // `a&&b|c` -> `a&&(b||c)`
+ binaryOperator().bind("p"))))
+ .bind("op"),
+ this);
+}
+
+void BoolBitwiseOperationCheck::check(const MatchFinder::MatchResult &Result) {
+ const auto *MatchedExpr = Result.Nodes.getNodeAs<BinaryOperator>("op");
+
+ auto DiagEmitter = [MatchedExpr, this] {
+ const NamedDecl *ND = getLHSNamedDeclIfCompoundAssign(MatchedExpr);
+ return diag(MatchedExpr->getOperatorLoc(),
+ "use logical operator '%0' for boolean %select{variable "
+ "%2|values}1 instead of bitwise operator '%3'")
+ << translate(MatchedExpr->getOpcodeStr()) << (ND == nullptr) << ND
+ << MatchedExpr->getOpcodeStr();
+ };
+
+ const bool HasVolatileOperand = llvm::any_of(
+ std::array{MatchedExpr->getLHS(), MatchedExpr->getRHS()},
+ [](const Expr *E) {
+ return E->IgnoreImpCasts()->getType().isVolatileQualified();
+ });
+ if (HasVolatileOperand)
+ return static_cast<void>(DiagEmitter());
+
+ const bool HasSideEffects = MatchedExpr->getRHS()->HasSideEffects(
+ *Result.Context, /*IncludePossibleEffects=*/!StrictMode);
+ if (HasSideEffects)
+ return static_cast<void>(DiagEmitter());
+
+ SourceLocation Loc = MatchedExpr->getOperatorLoc();
+
+ if (Loc.isInvalid() || Loc.isMacroID())
+ return static_cast<void>(IgnoreMacros || DiagEmitter());
+
+ Loc = Result.SourceManager->getSpellingLoc(Loc);
+ if (Loc.isInvalid() || Loc.isMacroID())
+ return static_cast<void>(IgnoreMacros || DiagEmitter());
+
+ const CharSourceRange TokenRange = CharSourceRange::getTokenRange(Loc);
+ if (TokenRange.isInvalid())
+ return static_cast<void>(IgnoreMacros || DiagEmitter());
+
+ const StringRef FixSpelling = translate(Lexer::getSourceText(
+ TokenRange, *Result.SourceManager, Result.Context->getLangOpts()));
+
+ if (FixSpelling.empty())
+ return static_cast<void>(DiagEmitter());
+
+ FixItHint InsertEqual;
+ if (MatchedExpr->isCompoundAssignmentOp()) {
+ const auto *DeclRefLHS =
+ dyn_cast<DeclRefExpr>(MatchedExpr->getLHS()->IgnoreImpCasts());
+ if (!DeclRefLHS)
+ return static_cast<void>(DiagEmitter());
+ const SourceLocation LocLHS = DeclRefLHS->getEndLoc();
+ if (LocLHS.isInvalid() || LocLHS.isMacroID())
+ return static_cast<void>(IgnoreMacros || DiagEmitter());
+ const SourceLocation InsertLoc = clang::Lexer::getLocForEndOfToken(
+ LocLHS, 0, *Result.SourceManager, Result.Context->getLangOpts());
+ if (InsertLoc.isInvalid() || InsertLoc.isMacroID())
+ return static_cast<void>(IgnoreMacros || DiagEmitter());
+ InsertEqual = FixItHint::CreateInsertion(
+ InsertLoc, " = " + DeclRefLHS->getDecl()->getNameAsString());
+ }
+
+ auto ReplaceOperator = FixItHint::CreateReplacement(TokenRange, FixSpelling);
+
+ const auto *Parent = Result.Nodes.getNodeAs<BinaryOperator>("p");
+ std::optional<BinaryOperatorKind> ParentOpcode;
+ if (Parent)
+ ParentOpcode = Parent->getOpcode();
+
+ const auto *RHS =
+ dyn_cast<BinaryOperator>(MatchedExpr->getRHS()->IgnoreImpCasts());
+ std::optional<BinaryOperatorKind> RHSOpcode;
+ if (RHS)
+ RHSOpcode = RHS->getOpcode();
+
+ const Expr *SurroundedExpr = nullptr;
+ if ((MatchedExpr->getOpcode() == BO_Or && ParentOpcode == BO_LAnd) ||
+ (MatchedExpr->getOpcode() == BO_And &&
+ llvm::is_contained({BO_Xor, BO_Or}, ParentOpcode))) {
+ const Expr *Side = Parent->getLHS()->IgnoreParenImpCasts() == MatchedExpr
+ ? Parent->getLHS()
+ : Parent->getRHS();
+ SurroundedExpr = Side->IgnoreImpCasts();
+ assert(SurroundedExpr->IgnoreParens() == MatchedExpr);
+ } else if (MatchedExpr->getOpcode() == BO_AndAssign && RHSOpcode == BO_LOr)
+ SurroundedExpr = RHS;
+
+ if (SurroundedExpr && isa<ParenExpr>(SurroundedExpr))
+ SurroundedExpr = nullptr;
+
+ FixItHint InsertBrace1;
+ FixItHint InsertBrace2;
+ if (SurroundedExpr) {
+ const SourceLocation InsertFirstLoc = SurroundedExpr->getBeginLoc();
+ const SourceLocation InsertSecondLoc = clang::Lexer::getLocForEndOfToken(
+ SurroundedExpr->getEndLoc(), 0, *Result.SourceManager,
+ Result.Context->getLangOpts());
+ if (InsertFirstLoc.isInvalid() || InsertFirstLoc.isMacroID() ||
+ InsertSecondLoc.isInvalid() || InsertSecondLoc.isMacroID())
+ return static_cast<void>(IgnoreMacros || DiagEmitter());
+ InsertBrace1 = FixItHint::CreateInsertion(InsertFirstLoc, "(");
+ InsertBrace2 = FixItHint::CreateInsertion(InsertSecondLoc, ")");
+ }
+
+ DiagEmitter() << InsertEqual << ReplaceOperator << InsertBrace1
+ << InsertBrace2;
+}
+
+} // namespace clang::tidy::misc
\ No newline at end of file
diff --git a/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.h b/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.h
new file mode 100644
index 0000000000000..b1056e53c50c9
--- /dev/null
+++ b/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.h
@@ -0,0 +1,42 @@
+//===--- BoolBitwiseOperationCheck.h - clang-tidy ---------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MISC_BOOLBITWISEOPERATIONCHECK_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MISC_BOOLBITWISEOPERATIONCHECK_H
+
+#include "../ClangTidyCheck.h"
+
+namespace clang::tidy::misc {
+
+/// Finds potentially inefficient use of bitwise operators such as ``&``, ``|``
+/// and their compound analogues on Boolean values where logical operators like
+/// ``&&`` and ``||`` would be more appropriate.
+///
+/// For the user-facing documentation see:
+/// http://clang.llvm.org/extra/clang-tidy/checks/misc/bool-bitwise-operation.html
+class BoolBitwiseOperationCheck : public ClangTidyCheck {
+public:
+ BoolBitwiseOperationCheck(StringRef Name, ClangTidyContext *Context);
+ void storeOptions(ClangTidyOptions::OptionMap &Options) override;
+ void registerMatchers(ast_matchers::MatchFinder *Finder) override;
+ void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
+ bool isLanguageVersionSupported(const LangOptions &LangOpts) const override {
+ return LangOpts.CPlusPlus || LangOpts.C99;
+ }
+ std::optional<TraversalKind> getCheckTraversalKind() const override {
+ return TK_IgnoreUnlessSpelledInSource;
+ }
+
+private:
+ bool StrictMode;
+ bool IgnoreMacros;
+};
+
+} // namespace clang::tidy::misc
+
+#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MISC_BOOLBITWISEOPERATIONCHECK_H
\ No newline at end of file
diff --git a/clang-tools-extra/clang-tidy/misc/CMakeLists.txt b/clang-tools-extra/clang-tidy/misc/CMakeLists.txt
index 2cfee5fd10713..21065eb5432fe 100644
--- a/clang-tools-extra/clang-tidy/misc/CMakeLists.txt
+++ b/clang-tools-extra/clang-tidy/misc/CMakeLists.txt
@@ -18,6 +18,7 @@ add_custom_target(genconfusable DEPENDS Confusables.inc)
set_target_properties(genconfusable PROPERTIES FOLDER "Clang Tools Extra/Sourcegenning")
add_clang_library(clangTidyMiscModule STATIC
+ BoolBitwiseOperationCheck.cpp
ConstCorrectnessCheck.cpp
CoroutineHostileRAIICheck.cpp
DefinitionsInHeadersCheck.cpp
diff --git a/clang-tools-extra/clang-tidy/misc/MiscTidyModule.cpp b/clang-tools-extra/clang-tidy/misc/MiscTidyModule.cpp
index 6f4af6c44dcb4..8221e07f3880c 100644
--- a/clang-tools-extra/clang-tidy/misc/MiscTidyModule.cpp
+++ b/clang-tools-extra/clang-tidy/misc/MiscTidyModule.cpp
@@ -9,6 +9,7 @@
#include "../ClangTidy.h"
#include "../ClangTidyModule.h"
#include "../ClangTidyModuleRegistry.h"
+#include "BoolBitwiseOperationCheck.h"
#include "ConfusableIdentifierCheck.h"
#include "ConstCorrectnessCheck.h"
#include "CoroutineHostileRAIICheck.h"
@@ -40,6 +41,8 @@ namespace misc {
class MiscModule : public ClangTidyModule {
public:
void addCheckFactories(ClangTidyCheckFactories &CheckFactories) override {
+ CheckFactories.registerCheck<BoolBitwiseOperationCheck>(
+ "misc-bool-bitwise-operation");
CheckFactories.registerCheck<ConfusableIdentifierCheck>(
"misc-confusable-identifiers");
CheckFactories.registerCheck<ConstCorrectnessCheck>(
diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst
index 8a0151f567c24..5ad73c43fa180 100644
--- a/clang-tools-extra/docs/ReleaseNotes.rst
+++ b/clang-tools-extra/docs/ReleaseNotes.rst
@@ -210,6 +210,13 @@ New checks
Finds calls to STL library iterator algorithms that could be replaced with
LLVM range-based algorithms from ``llvm/ADT/STLExtras.h``.
+- New :doc:`misc-bool-bitwise-operation
+ <clang-tidy/checks/misc/bool-bitwise-operation>` check.
+
+ Finds potentially inefficient use of bitwise operators such as ``&``, ``|``
+ and their compound analogues on Boolean values where logical operators like
+ ``&&`` and ``||`` would be more appropriate.
+
- New :doc:`misc-override-with-different-visibility
<clang-tidy/checks/misc/override-with-different-visibility>` check.
diff --git a/clang-tools-extra/docs/clang-tidy/checks/list.rst b/clang-tools-extra/docs/clang-tidy/checks/list.rst
index a324d18704c01..d1344d4c47f8c 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/list.rst
+++ b/clang-tools-extra/docs/clang-tidy/checks/list.rst
@@ -174,7 +174,9 @@ Clang-Tidy Checks
:doc:`bugprone-use-after-move <bugprone/use-after-move>`,
:doc:`bugprone-virtual-near-miss <bugprone/virtual-near-miss>`, "Yes"
:doc:`cert-dcl58-cpp <cert/dcl58-cpp>`,
+ :doc:`cert-env33-c <cert/env33-c>`,
:doc:`cert-err33-c <cert/err33-c>`,
+ :doc:`cert-err52-cpp <cert/err52-cpp>`,
:doc:`cert-err60-cpp <cert/err60-cpp>`,
:doc:`cert-flp30-c <cert/flp30-c>`,
:doc:`cert-mem57-cpp <cert/mem57-cpp>`,
@@ -261,6 +263,7 @@ Clang-Tidy Checks
:doc:`llvmlibc-implementation-in-namespace <llvmlibc/implementation-in-namespace>`,
:doc:`llvmlibc-inline-function-decl <llvmlibc/inline-function-decl>`, "Yes"
:doc:`llvmlibc-restrict-system-libc-headers <llvmlibc/restrict-system-libc-headers>`, "Yes"
+ :doc:`misc-bool-bitwise-operation <misc/bool-bitwise-operation>`, "Yes"
:doc:`misc-confusable-identifiers <misc/confusable-identifiers>`,
:doc:`misc-const-correctness <misc/const-correctness>`, "Yes"
:doc:`misc-coroutine-hostile-raii <misc/coroutine-hostile-raii>`,
@@ -372,7 +375,7 @@ Clang-Tidy Checks
:doc:`readability-avoid-nested-conditional-operator <readability/avoid-nested-conditional-operator>`,
:doc:`readability-avoid-return-with-void-value <readability/avoid-return-with-void-value>`, "Yes"
:doc:`readability-avoid-unconditional-preprocessor-if <readability/avoid-unconditional-preprocessor-if>`,
- :doc:`readability-braces-around-statements <readability/braces-around-statements>`, "Yes"
+ :doc:`readability-braces-around-statements <readability/braces-around-statements>`,
:doc:`readability-const-return-type <readability/const-return-type>`, "Yes"
:doc:`readability-container-contains <readability/container-contains>`, "Yes"
:doc:`readability-container-data-pointer <readability/container-data-pointer>`, "Yes"
@@ -442,9 +445,7 @@ Check aliases
:doc:`cert-dcl54-cpp <cert/dcl54-cpp>`, :doc:`misc-new-delete-overloads <misc/new-delete-overloads>`,
:doc:`cert-dcl59-cpp <cert/dcl59-cpp>`, :doc:`google-build-namespaces <google/build-namespaces>`,
:doc:`cert-err09-cpp <cert/err09-cpp>`, :doc:`misc-throw-by-value-catch-by-reference <misc/throw-by-value-catch-by-reference>`,
- :doc:`cert-env33-c <cert/env33-c>`, :doc:`bugprone-command-processor <bugprone/command-processor>`,
:doc:`cert-err34-c <cert/err34-c>`, :doc:`bugprone-unchecked-string-to-number-conversion <bugprone/unchecked-string-to-number-conversion>`,
- :doc:`cert-err52-cpp <cert/err52-cpp>`, :doc:`modernize-avoid-setjmp-longjmp <modernize/avoid-setjmp-longjmp>`,
:doc:`cert-err58-cpp <cert/err58-cpp>`, :doc:`bugprone-throwing-static-initialization <bugprone/throwing-static-initialization>`,
:doc:`cert-err61-cpp <cert/err61-cpp>`, :doc:`misc-throw-by-value-catch-by-reference <misc/throw-by-value-catch-by-reference>`,
:doc:`cert-exp42-c <cert/exp42-c>`, :doc:`bugprone-suspicious-memory-comparison <bugprone/suspicious-memory-comparison>`,
@@ -571,12 +572,12 @@ Check aliases
:doc:`cppcoreguidelines-non-private-member-variables-in-classes <cppcoreguidelines/non-private-member-variables-in-classes>`, :doc:`misc-non-private-member-variables-in-classes <misc/non-private-member-variables-in-classes>`,
:doc:`cppcoreguidelines-use-default-member-init <cppcoreguidelines/use-default-member-init>`, :doc:`modernize-use-default-member-init <modernize/use-default-member-init>`, "Yes"
:doc:`fuchsia-header-anon-namespaces <fuchsia/header-anon-namespaces>`, :doc:`google-build-namespaces <google/build-namespaces>`,
- :doc:`google-readability-braces-around-statements <google/readability-braces-around-statements>`, :doc:`readability-braces-around-statements <readability/braces-around-statements>`, "Yes"
+ :doc:`google-readability-braces-around-statements <google/readability-braces-around-statements>`, :doc:`readability-braces-around-statements <readability/braces-around-statements>`,
:doc:`google-readability-function-size <google/readability-function-size>`, :doc:`readability-function-size <readability/function-size>`,
:doc:`google-readability-namespace-comments <google/readability-namespace-comments>`, :doc:`llvm-namespace-comment <llvm/namespace-comment>`,
:doc:`hicpp-avoid-c-arrays <hicpp/avoid-c-arrays>`, :doc:`modernize-avoid-c-arrays <modernize/avoid-c-arrays>`,
:doc:`hicpp-avoid-goto <hicpp/avoid-goto>`, :doc:`cppcoreguidelines-avoid-goto <cppcoreguidelines/avoid-goto>`,
- :doc:`hicpp-braces-around-statements <hicpp/braces-around-statements>`, :doc:`readability-braces-around-statements <readability/braces-around-statements>`, "Yes"
+ :doc:`hicpp-braces-around-statements <hicpp/braces-around-statements>`, :doc:`readability-braces-around-statements <readability/braces-around-statements>`,
:doc:`hicpp-deprecated-headers <hicpp/deprecated-headers>`, :doc:`modernize-deprecated-headers <modernize/deprecated-headers>`, "Yes"
:doc:`hicpp-explicit-conversions <hicpp/explicit-conversions>`, :doc:`google-explicit-constructor <google/explicit-constructor>`, "Yes"
:doc:`hicpp-function-size <hicpp/function-size>`, :doc:`readability-function-size <readability/function-size>`,
diff --git a/clang-tools-extra/docs/clang-tidy/checks/misc/bool-bitwise-operation.rst b/clang-tools-extra/docs/clang-tidy/checks/misc/bool-bitwise-operation.rst
new file mode 100644
index 0000000000000..3682a74a5119d
--- /dev/null
+++ b/clang-tools-extra/docs/clang-tidy/checks/misc/bool-bitwise-operation.rst
@@ -0,0 +1,62 @@
+.. title:: clang-tidy - misc-bool-bitwise-operation
+
+misc-bool-bitwise-operation
+===========================
+
+Finds potentially inefficient use of bitwise operators such as ``&``, ``|``
+and their compound analogues on Boolean values where logical operators like
+``&&`` and ``||`` would be more appropriate.
+
+Bitwise operations on Booleans can incur unnecessary performance overhead due
+to implicit integer conversions and missed short-circuit evaluation.
+
+.. code-block:: c++
+
+ bool invalid = false;
+ invalid |= x > limit.x; // warning: use logical operator '||' for boolean variable 'invalid' instead of bitwise operator '|='
+ invalid |= y > limit.y; // warning: use logical operator '||' for boolean variable 'invalid' instead of bitwise operator '|='
+ invalid |= z > limit.z; // warning: use logical operator '||' for boolean variable 'invalid' instead of bitwise operator '|='
+ if (invalid) {
+ // error handling
+ }
+
+These 3 warnings suggest assigning the result of a logical ``||`` operation
+instead of using the ``|=`` operator:
+
+.. code-block:: c++
+
+ bool invalid = false;
+ invalid = invalid || x > limit.x;
+ invalid = invalid || y > limit.x;
+ invalid = invalid || z > limit.z;
+ if (invalid) {
+ // error handling
+ }
+
+Limitations
+-----------
+
+* Bitwise operators inside templates aren't matched.
+
+.. code-block:: c++
+
+ template <typename X>
+ void f(X a, X b) {
+ a | b;
+ }
+
+ // even 'f(true, false)' (or similar) won't trigger the warning.
+
+Options
+-------
+
+.. option:: StrictMode
+
+ Enabling this option promotes more fix-it hints even when they might
+ change evaluation order or skip side effects. Default value is `false`.
+
+.. option:: IgnoreMacros
+
+ This option disables the warning if a macro inside the expression body
+ prevents replacing a bitwise operator with a logical one. Default value
+ is `false`.
\ No newline at end of file
diff --git a/clang-tools-extra/test/clang-tidy/checkers/misc/bool-bitwise-operation-change-possible-side-effect.cpp b/clang-tools-extra/test/clang-tidy/checkers/misc/bool-bitwise-operation-change-possible-side-effect.cpp
new file mode 100644
index 0000000000000..a92d32f55701f
--- /dev/null
+++ b/clang-tools-extra/test/clang-tidy/checkers/misc/bool-bitwise-operation-change-possible-side-effect.cpp
@@ -0,0 +1,82 @@
+// RUN: %check_clang_tidy %s misc-bool-bitwise-operation %t \
+// RUN: -config="{CheckOptions: { \
+// RUN: misc-bool-bitwise-operation.StrictMode: true }}"
+
+bool function_with_possible_side_effects();
+
+void bad_possible_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 '|' [misc-bool-bitwise-operation]
+ // CHECK-FIXES: a || function_with_possible_side_effects();
+
+ a & function_with_possible_side_effects();
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '&&' for boolean values instead of bitwise operator '&' [misc-bool-bitwise-operation]
+ // CHECK-FIXES: a && function_with_possible_side_effects();
+
+ a |= function_with_possible_side_effects();
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '||' for boolean variable 'a' instead of bitwise operator '|=' [misc-bool-bitwise-operation]
+ // CHECK-FIXES: a = a || function_with_possible_side_effects();
+
+ a &= function_with_possible_side_effects();
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '&&' for boolean variable 'a' instead of bitwise operator '&=' [misc-bool-bitwise-operation]
+ // CHECK-FIXES: a = a && function_with_possible_side_effects();
+
+ bool c = true;
+
+ a &= function_with_possible_side_effects() && c;
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '&&' for boolean variable 'a' instead of bitwise operator '&=' [misc-bool-bitwise-operation]
+ // CHECK-FIXES: a = a && function_with_possible_side_effects() && c;
+
+ a &= b && function_with_possible_side_effects();
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '&&' for boolean variable 'a' instead of bitwise operator '&=' [misc-bool-bitwise-operation]
+ // CHECK-FIXES: a = a && b && function_with_possible_side_effects();
+
+ a |= function_with_possible_side_effects() || c;
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '||' for boolean variable 'a' instead of bitwise operator '|=' [misc-bool-bitwise-operation]
+ // CHECK-FIXES: a = a || function_with_possible_side_effects() || c;
+
+ a |= b || function_with_possible_side_effects();
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '||' for boolean variable 'a' instead of bitwise operator '|=' [misc-bool-bitwise-operation]
+ // CHECK-FIXES: a = a || b || function_with_possible_side_effects();
+}
+
+void bad_definitely_side_effects() {
+ bool a = true, b = false;
+ int acc = 0;
+
+ a | (acc++, b);
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES-NOT: :[[@LINE-2]]:{{.*}}: note: FIX-IT applied suggested code changes
+
+ a & (acc++, b);
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '&&' for boolean values instead of bitwise operator '&' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES-NOT: :[[@LINE-2]]:{{.*}}: note: FIX-IT applied suggested code changes
+
+ a |= (acc++, b);
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '||' for boolean variable 'a' instead of bitwise operator '|=' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES-NOT: :[[@LINE-2]]:{{.*}}: note: FIX-IT applied suggested code changes
+
+ a &= (acc++, b);
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '&&' for boolean variable 'a' instead of bitwise operator '&=' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES-NOT: :[[@LINE-2]]:{{.*}}: note: FIX-IT applied suggested code changes
+
+ bool c = true;
+
+ a &= (acc++, b) && c;
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '&&' for boolean variable 'a' instead of bitwise operator '&=' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES-NOT: :[[@LINE-2]]:{{.*}}: note: FIX-IT applied suggested code changes
+
+ a &= b && (acc++, c);
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '&&' for boolean variable 'a' instead of bitwise operator '&=' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES-NOT: :[[@LINE-2]]:{{.*}}: note: FIX-IT applied suggested code changes
+
+ a |= (acc++, b) || c;
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '||' for boolean variable 'a' instead of bitwise operator '|=' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES-NOT: :[[@LINE-2]]:{{.*}}: note: FIX-IT applied suggested code changes
+
+ a |= b || (acc++, c);
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '||' for boolean variable 'a' instead of bitwise operator '|=' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES-NOT: :[[@LINE-2]]:{{.*}}: note: FIX-IT applied suggested code changes
+}
\ No newline at end of file
diff --git a/clang-tools-extra/test/clang-tidy/checkers/misc/bool-bitwise-operation-ignore-macros.cpp b/clang-tools-extra/test/clang-tidy/checkers/misc/bool-bitwise-operation-ignore-macros.cpp
new file mode 100644
index 0000000000000..5b879063bae6b
--- /dev/null
+++ b/clang-tools-extra/test/clang-tidy/checkers/misc/bool-bitwise-operation-ignore-macros.cpp
@@ -0,0 +1,53 @@
+// RUN: %check_clang_tidy %s misc-bool-bitwise-operation %t \
+// RUN: -config="{CheckOptions: { \
+// RUN: misc-bool-bitwise-operation.IgnoreMacros: true }}"
+
+#define CAT(a, b) a ## b
+#define IDENT(a) a
+
+void bad_in_macro() {
+ bool a = true, b = false;
+
+ // change operator - BAD
+ IDENT(a |) b;
+ a IDENT(& b);
+ IDENT(a |=) b;
+ a IDENT(&= b);
+
+ // change operator - GOOD
+ IDENT(a) | b;
+ // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-FIXES: IDENT(a) || b;
+ a & IDENT(b);
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '&&' for boolean values instead of bitwise operator '&' [misc-bool-bitwise-operation]
+ // CHECK-FIXES: a && IDENT(b);
+ IDENT(a) & IDENT(b);
+ // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: use logical operator '&&' for boolean values instead of bitwise operator '&' [misc-bool-bitwise-operation]
+ // CHECK-FIXES: IDENT(a) && IDENT(b);
+
+ // insert `)` - BAD
+ bool c = true, e = false;
+ a && b | IDENT(c &&) e;
+
+ // insert `)` - GOOD
+ a && b | c IDENT(&& e);
+ // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-FIXES: a && (b || c) IDENT(&& e);
+
+ // insert `(` - BAD
+ a IDENT(&& b) | c && e;
+
+ // insert `(` - GOOD
+ IDENT(a &&) b | c && e;
+ // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-FIXES: IDENT(a &&) (b || c) && e;
+
+ bool ab = false;
+ // insert ` = a` - BAD
+ CAT(a, b) &= b;
+
+ // insert ` = a`- GOOD
+ b &= CAT(a, b);
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '&&' for boolean variable 'b' instead of bitwise operator '&=' [misc-bool-bitwise-operation]
+ // CHECK-FIXES: b = b && CAT(a, b);
+}
\ No newline at end of file
diff --git a/clang-tools-extra/test/clang-tidy/checkers/misc/bool-bitwise-operation-nontraditional.cpp b/clang-tools-extra/test/clang-tidy/checkers/misc/bool-bitwise-operation-nontraditional.cpp
new file mode 100644
index 0000000000000..d0700dbe309b5
--- /dev/null
+++ b/clang-tools-extra/test/clang-tidy/checkers/misc/bool-bitwise-operation-nontraditional.cpp
@@ -0,0 +1,399 @@
+// RUN: %check_clang_tidy %s misc-bool-bitwise-operation %t
+
+bool& normal() {
+ int a = 100, b = 200;
+
+ a bitor b;
+ a bitand b;
+ a or_eq b;
+ a and_eq b;
+
+ static bool st = false;
+ return st;
+}
+
+bool bad() noexcept __attribute__((pure)) {
+ bool a = true, b = false;
+ a bitor b;
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-FIXES: a or b;
+ a bitand b;
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '&&' for boolean values instead of bitwise operator '&' [misc-bool-bitwise-operation]
+ // CHECK-FIXES: a and b;
+ a or_eq b;
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '||' for boolean variable 'a' instead of bitwise operator '|=' [misc-bool-bitwise-operation]
+ // CHECK-FIXES: a = a or b;
+ a and_eq b;
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '&&' for boolean variable 'a' instead of bitwise operator '&=' [misc-bool-bitwise-operation]
+ // CHECK-FIXES: a = a and b;
+
+ return true;
+}
+
+bool global_1 = bad() bitor bad();
+// CHECK-MESSAGES: :[[@LINE-1]]:23: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+// CHECK-FIXES: bool global_1 = bad() or bad();
+bool global_2 = bad() bitand bad();
+// CHECK-MESSAGES: :[[@LINE-1]]:23: warning: use logical operator '&&' for boolean values instead of bitwise operator '&' [misc-bool-bitwise-operation]
+// CHECK-FIXES: bool global_2 = bad() and bad();
+
+using Boolean = bool;
+
+bool bad_typedef() {
+ Boolean a = true, b = false;
+ a bitor b;
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-FIXES: a or b;
+ a bitand b;
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '&&' for boolean values instead of bitwise operator '&' [misc-bool-bitwise-operation]
+ // CHECK-FIXES: a and b;
+ a or_eq b;
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '||' for boolean variable 'a' instead of bitwise operator '|=' [misc-bool-bitwise-operation]
+ // CHECK-FIXES: a = a or b;
+ a and_eq b;
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '&&' for boolean variable 'a' instead of bitwise operator '&=' [misc-bool-bitwise-operation]
+ // CHECK-FIXES: a = a and b;
+ return true;
+}
+
+bool function_with_possible_side_effects();
+
+void bad_side_effects() {
+ bool a = true, b = false;
+
+ a bitor function_with_possible_side_effects();
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES-NOT: :[[@LINE-2]]:{{.*}}: note: FIX-IT applied suggested code changes
+
+ a bitand function_with_possible_side_effects();
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '&&' for boolean values instead of bitwise operator '&' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES-NOT: :[[@LINE-2]]:{{.*}}: note: FIX-IT applied suggested code changes
+
+ function_with_possible_side_effects() bitor a;
+ // CHECK-MESSAGES: :[[@LINE-1]]:43: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-FIXES: function_with_possible_side_effects() or a;
+
+ function_with_possible_side_effects() bitand a;
+ // CHECK-MESSAGES: :[[@LINE-1]]:43: warning: use logical operator '&&' for boolean values instead of bitwise operator '&' [misc-bool-bitwise-operation]
+ // CHECK-FIXES: function_with_possible_side_effects() and a;
+ a or_eq function_with_possible_side_effects();
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '||' for boolean variable 'a' instead of bitwise operator '|=' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES-NOT: :[[@LINE-2]]:{{.*}}: note: FIX-IT applied suggested code changes
+
+ a and_eq function_with_possible_side_effects();
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '&&' for boolean variable 'a' instead of bitwise operator '&=' [misc-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 or function_with_possible_side_effects() bitor c;
+ // CHECK-MESSAGES: :[[@LINE-1]]:48: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-FIXES: a or function_with_possible_side_effects() or c;
+
+ function_with_possible_side_effects() or b bitor c;
+ // CHECK-MESSAGES: :[[@LINE-1]]:48: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-FIXES: function_with_possible_side_effects() or b or c;
+
+ a and function_with_possible_side_effects() bitand c;
+ // CHECK-MESSAGES: :[[@LINE-1]]:49: warning: use logical operator '&&' for boolean values instead of bitwise operator '&' [misc-bool-bitwise-operation]
+ // CHECK-FIXES: a and function_with_possible_side_effects() and c;
+
+ function_with_possible_side_effects() and b bitand c;
+ // CHECK-MESSAGES: :[[@LINE-1]]:49: warning: use logical operator '&&' for boolean values instead of bitwise operator '&' [misc-bool-bitwise-operation]
+ // CHECK-FIXES: function_with_possible_side_effects() and b and c;
+
+ // but here the count of evaluation migh be changed - no fix must be provided
+
+ a and_eq function_with_possible_side_effects() and c;
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '&&' for boolean variable 'a' instead of bitwise operator '&=' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES-NOT: :[[@LINE-2]]:{{.*}}: note: FIX-IT applied suggested code changes
+
+ a and_eq b and function_with_possible_side_effects();
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '&&' for boolean variable 'a' instead of bitwise operator '&=' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES-NOT: :[[@LINE-2]]:{{.*}}: note: FIX-IT applied suggested code changes
+
+ a or_eq function_with_possible_side_effects() or c;
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '||' for boolean variable 'a' instead of bitwise operator '|=' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES-NOT: :[[@LINE-2]]:{{.*}}: note: FIX-IT applied suggested code changes
+
+ a or_eq b or function_with_possible_side_effects();
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '||' for boolean variable 'a' instead of bitwise operator '|=' [misc-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 bitor b;
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES-NOT: :[[@LINE-2]]:{{.*}}: note: FIX-IT applied suggested code changes
+ a bitand b;
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '&&' for boolean values instead of bitwise operator '&' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES-NOT: :[[@LINE-2]]:{{.*}}: note: FIX-IT applied suggested code changes
+
+ a or_eq b;
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '||' for boolean variable 'a' instead of bitwise operator '|=' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES-NOT: :[[@LINE-2]]:{{.*}}: note: FIX-IT applied suggested code changes
+ a and_eq b;
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '&&' for boolean variable 'a' instead of bitwise operator '&=' [misc-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 and b bitor c;
+ // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-FIXES: a and (b or c);
+ a and b bitand c;
+ // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use logical operator '&&' for boolean values instead of bitwise operator '&' [misc-bool-bitwise-operation]
+ // CHECK-FIXES: a and b and c;
+ a or b bitand c;
+ // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: use logical operator '&&' for boolean values instead of bitwise operator '&' [misc-bool-bitwise-operation]
+ // CHECK-FIXES: a or b and c;
+ a or b bitor c;
+ // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-FIXES: a or b or c;
+ b bitor c and a;
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-FIXES: (b or c) and a;
+
+ bool q = (true and false bitor true) and (false bitor true and (false and true bitor false));
+ // CHECK-MESSAGES: :[[@LINE-1]]:30: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-2]]:53: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-3]]:84: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-FIXES: bool q = (true and (false or true)) and ((false or true) and (false and (true or false)));
+}
+
+void bad_with_priors2() {
+ bool a = false, b = true, c = true;
+ a xor b bitand c;
+ // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use logical operator '&&' for boolean values instead of bitwise operator '&' [misc-bool-bitwise-operation]
+ // CHECK-FIXES: a xor (b and c);
+
+ // braces added in the first change
+ a bitor b bitand c;
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-2]]:15: warning: use logical operator '&&' for boolean values instead of bitwise operator '&' [misc-bool-bitwise-operation]
+ // CHECK-FIXES: a or (b and c);
+
+ b bitand c xor a;
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '&&' for boolean values instead of bitwise operator '&' [misc-bool-bitwise-operation]
+ // CHECK-FIXES: (b and c) xor a;
+
+ // braces added in the first change
+ b bitand c bitor a;
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '&&' for boolean values instead of bitwise operator '&' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-2]]:16: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-FIXES: (b and c) or 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 xor (a and b bitand c);
+ // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: use logical operator '&&' for boolean values instead of bitwise operator '&' [misc-bool-bitwise-operation]
+ // CHECK-FIXES: d xor (a and b and c);
+
+ a xor ident(b bitand c or a);
+ // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: use logical operator '&&' for boolean values instead of bitwise operator '&' [misc-bool-bitwise-operation]
+ // CHECK-FIXES: a xor ident(b and c or a);
+
+ a bitor ident(a ? b bitand c : c);
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-2]]:25: warning: use logical operator '&&' for boolean values instead of bitwise operator '&' [misc-bool-bitwise-operation]
+ // CHECK-FIXES: a bitor ident(a ? b and c : c);
+}
+
+void bad_with_priors_already_braced() {
+ bool a = false, b = true, c = true;
+ a and (b bitor c);
+ // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-FIXES: a and (b or c);
+ (b bitor c) and a;
+ // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-FIXES: (b or c) and a;
+
+ bool q = (true and (false bitor true)) and ((false bitor true) and (false and (true bitor false)));
+ // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-2]]:56: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-3]]:89: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-FIXES: bool q = (true and (false or true)) and ((false or true) and (false and (true or false)));
+
+ a xor (b bitand c);
+ // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: use logical operator '&&' for boolean values instead of bitwise operator '&' [misc-bool-bitwise-operation]
+ // CHECK-FIXES: a xor (b and c);
+
+ a bitor (b bitand c);
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-2]]:16: warning: use logical operator '&&' for boolean values instead of bitwise operator '&' [misc-bool-bitwise-operation]
+ // CHECK-FIXES: a or (b and c);
+
+ (b bitand c) xor a;
+ // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: use logical operator '&&' for boolean values instead of bitwise operator '&' [misc-bool-bitwise-operation]
+ // CHECK-FIXES: (b and c) xor a;
+
+ (b bitand c) bitor a;
+ // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: use logical operator '&&' for boolean values instead of bitwise operator '&' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-2]]:18: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-FIXES: (b and c) or a;
+}
+
+void bad_with_priors_compound() {
+ bool a = false, b = true, c = true;
+ a and_eq b or c;
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '&&' for boolean variable 'a' instead of bitwise operator '&=' [misc-bool-bitwise-operation]
+ // CHECK-FIXES: a = a and (b or c);
+ a or_eq b or c;
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '||' for boolean variable 'a' instead of bitwise operator '|=' [misc-bool-bitwise-operation]
+ // CHECK-FIXES: a = a or b or c;
+ a and_eq b and c;
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '&&' for boolean variable 'a' instead of bitwise operator '&=' [misc-bool-bitwise-operation]
+ // CHECK-FIXES: a = a and b and c;
+ a or_eq b and c;
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '||' for boolean variable 'a' instead of bitwise operator '|=' [misc-bool-bitwise-operation]
+ // CHECK-FIXES: a = a or b and c;
+}
+
+void bad_with_priors_compound_already_braced() {
+ bool a = false, b = true, c = true;
+ a and_eq (b or c);
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '&&' for boolean variable 'a' instead of bitwise operator '&=' [misc-bool-bitwise-operation]
+ // CHECK-FIXES: a = a and (b or c);
+}
+
+void bad_no_fixit() {
+ bool b = false;
+ normal() or_eq b;
+ // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: use logical operator '||' for boolean values instead of bitwise operator '|=' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES-NOT: :[[@LINE-2]]:{{.*}}: note: FIX-IT applied suggested code changes
+ normal() and_eq b;
+ // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: use logical operator '&&' for boolean values instead of bitwise operator '&=' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES-NOT: :[[@LINE-2]]:{{.*}}: note: FIX-IT applied suggested code changes
+}
+
+#define MY_OR bitor
+#define MY_AND bitand
+#define MY_OR_ASSIGN or_eq
+#define MY_AND_ASSIGN and_eq
+#define MY_LOG_AND and
+
+#define CAT(a, b) a ## b
+#define IDENT(a) a
+
+void bad_in_macro() {
+ bool a = true, b = false;
+
+ // change operator - BAD
+ IDENT(a bitor) b;
+ // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES-NOT: :[[@LINE-2]]:{{.*}}: note: FIX-IT applied suggested code changes
+ a IDENT(bitand b);
+ // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use logical operator '&&' for boolean values instead of bitwise operator '&' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES-NOT: :[[@LINE-2]]:{{.*}}: note: FIX-IT applied suggested code changes
+ IDENT(a or_eq) b;
+ // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use logical operator '||' for boolean variable 'a' instead of bitwise operator '|=' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES-NOT: :[[@LINE-2]]:{{.*}}: note: FIX-IT applied suggested code changes
+ a IDENT(and_eq b);
+ // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use logical operator '&&' for boolean variable 'a' instead of bitwise operator '&=' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES-NOT: :[[@LINE-2]]:{{.*}}: note: FIX-IT applied suggested code changes
+
+ // change operator - GOOD
+ IDENT(a) bitor b;
+ // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-FIXES: IDENT(a) or b;
+ a bitand IDENT(b);
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '&&' for boolean values instead of bitwise operator '&' [misc-bool-bitwise-operation]
+ // CHECK-FIXES: a and IDENT(b);
+ IDENT(a) bitand IDENT(b);
+ // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: use logical operator '&&' for boolean values instead of bitwise operator '&' [misc-bool-bitwise-operation]
+ // CHECK-FIXES: IDENT(a) and IDENT(b);
+
+ // insert `)` - BAD
+ bool c = true, e = false;
+ a and b bitor IDENT(c and) e;
+ // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES-NOT: :[[@LINE-2]]:{{.*}}: note: FIX-IT applied suggested code changes
+
+ // insert `)` - GOOD
+ a and b bitor c IDENT(and e);
+ // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-FIXES: a and (b or c) IDENT(and e);
+
+ // insert `(` - BAD
+ a IDENT(and b) bitor c and e;
+ // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES-NOT: :[[@LINE-2]]:{{.*}}: note: FIX-IT applied suggested code changes
+
+ // insert `(` - GOOD
+ IDENT(a and) b bitor c and e;
+ // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-FIXES: IDENT(a and) (b or c) and e;
+
+ bool ab = false;
+ // insert ` = a` - BAD
+ CAT(a, b) and_eq b;
+ // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: use logical operator '&&' for boolean variable 'ab' instead of bitwise operator '&=' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES-NOT: :[[@LINE-2]]:{{.*}}: note: FIX-IT applied suggested code changes
+
+ // insert ` = a`- GOOD
+ b and_eq CAT(a, b);
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '&&' for boolean variable 'b' instead of bitwise operator '&=' [misc-bool-bitwise-operation]
+ // CHECK-FIXES: b = b and CAT(a, b);
+}
+
+void bad_in_macro_fixit() {
+ bool a = true, b = false;
+
+ // FIXME: implement fixit for all of these cases
+
+ a MY_OR b;
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ a MY_AND b;
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '&&' for boolean values instead of bitwise operator '&' [misc-bool-bitwise-operation]
+ a MY_OR_ASSIGN b;
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '||' for boolean variable 'a' instead of bitwise operator '|=' [misc-bool-bitwise-operation]
+ a MY_AND_ASSIGN b;
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '&&' for boolean variable 'a' instead of bitwise operator '&=' [misc-bool-bitwise-operation]
+ IDENT(a and_eq b);
+ // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use logical operator '&&' for boolean variable 'a' instead of bitwise operator '&=' [misc-bool-bitwise-operation]
+}
+
+template<typename T>
+void good_in_unreachable_template(T a, T b) {
+ a bitor b;
+ a bitand b;
+ a or_eq b;
+ a and_eq b;
+}
+
+template<typename T>
+int bad_in_template(T a, T b) {
+ bool c = false;
+ // FIXME: at least warning should be provided in these cases
+ // a bitor b;
+ // a bitand b;
+ // a or_eq b;
+ // a and_eq b;
+ // c and_eq a;
+ return 0;
+}
+
+template<typename T>
+int bad_in_template_lamnda_captured(T a, T b) {
+ [=] mutable {
+ bool c = false;
+ // FIXME: at least warning should be provided in these cases
+ // a bitor b;
+ // a bitand b;
+ // a or_eq b;
+ // b and_eq a;
+ }();
+ return 0;
+}
+
+int dummy = bad_in_template(true, false) + bad_in_template_lamnda_captured(false, true);
\ No newline at end of file
diff --git a/clang-tools-extra/test/clang-tidy/checkers/misc/bool-bitwise-operation.c b/clang-tools-extra/test/clang-tidy/checkers/misc/bool-bitwise-operation.c
new file mode 100644
index 0000000000000..777189f12bbd3
--- /dev/null
+++ b/clang-tools-extra/test/clang-tidy/checkers/misc/bool-bitwise-operation.c
@@ -0,0 +1,26 @@
+// RUN: %check_clang_tidy %s misc-bool-bitwise-operation %t
+
+void normal() {
+ int a = 100, b = 200;
+
+ a | b;
+ a & b;
+ a |= b;
+ a &= b;
+}
+
+void bad() {
+ _Bool a = 1, b = 0;
+ a | b;
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-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 '&' [misc-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 '|=' [misc-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 '&=' [misc-bool-bitwise-operation]
+ // CHECK-FIXES: a = a && b;
+}
\ No newline at end of file
diff --git a/clang-tools-extra/test/clang-tidy/checkers/misc/bool-bitwise-operation.cpp b/clang-tools-extra/test/clang-tidy/checkers/misc/bool-bitwise-operation.cpp
new file mode 100644
index 0000000000000..86db240bb6efb
--- /dev/null
+++ b/clang-tools-extra/test/clang-tidy/checkers/misc/bool-bitwise-operation.cpp
@@ -0,0 +1,399 @@
+// RUN: %check_clang_tidy %s misc-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 '|' [misc-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 '&' [misc-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 '|=' [misc-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 '&=' [misc-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 '|' [misc-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 '&' [misc-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 '|' [misc-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 '&' [misc-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 '|=' [misc-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 '&=' [misc-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 '|' [misc-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 '&' [misc-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 '|' [misc-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 '&' [misc-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 '|=' [misc-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 '&=' [misc-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 '|' [misc-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 '|' [misc-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 '&' [misc-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 '&' [misc-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 '&=' [misc-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 '&=' [misc-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 '|=' [misc-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 '|=' [misc-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 '|' [misc-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 '&' [misc-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 '|=' [misc-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 '&=' [misc-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 '|' [misc-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 '&' [misc-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 '&' [misc-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 '|' [misc-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 '|' [misc-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 '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-2]]:47: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-3]]:72: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-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 '&' [misc-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 '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-2]]:11: warning: use logical operator '&&' for boolean values instead of bitwise operator '&' [misc-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 '&' [misc-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 '&' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-2]]:11: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-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 '&' [misc-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 '&' [misc-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 '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-2]]:21: warning: use logical operator '&&' for boolean values instead of bitwise operator '&' [misc-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 '|' [misc-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 '|' [misc-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 '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-2]]:50: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-3]]:77: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-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 '&' [misc-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 '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-2]]:12: warning: use logical operator '&&' for boolean values instead of bitwise operator '&' [misc-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 '&' [misc-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 '&' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-2]]:13: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-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 '&=' [misc-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 '|=' [misc-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 '&=' [misc-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 '|=' [misc-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 '&=' [misc-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 '|=' [misc-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 '&=' [misc-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
+ IDENT(a |) b;
+ // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES-NOT: :[[@LINE-2]]:{{.*}}: note: FIX-IT applied suggested code changes
+ a IDENT(& b);
+ // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use logical operator '&&' for boolean values instead of bitwise operator '&' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES-NOT: :[[@LINE-2]]:{{.*}}: note: FIX-IT applied suggested code changes
+ IDENT(a |=) b;
+ // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use logical operator '||' for boolean variable 'a' instead of bitwise operator '|=' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES-NOT: :[[@LINE-2]]:{{.*}}: note: FIX-IT applied suggested code changes
+ a IDENT(&= b);
+ // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use logical operator '&&' for boolean variable 'a' instead of bitwise operator '&=' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES-NOT: :[[@LINE-2]]:{{.*}}: note: FIX-IT applied suggested code changes
+
+ // change operator - GOOD
+ IDENT(a) | b;
+ // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-FIXES: IDENT(a) || b;
+ a & IDENT(b);
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '&&' for boolean values instead of bitwise operator '&' [misc-bool-bitwise-operation]
+ // CHECK-FIXES: a && IDENT(b);
+ IDENT(a) & IDENT(b);
+ // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: use logical operator '&&' for boolean values instead of bitwise operator '&' [misc-bool-bitwise-operation]
+ // CHECK-FIXES: IDENT(a) && IDENT(b);
+
+ // insert `)` - BAD
+ bool c = true, e = false;
+ a && b | IDENT(c &&) e;
+ // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES-NOT: :[[@LINE-2]]:{{.*}}: note: FIX-IT applied suggested code changes
+
+ // insert `)` - GOOD
+ a && b | c IDENT(&& e);
+ // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-FIXES: a && (b || c) IDENT(&& e);
+
+ // insert `(` - BAD
+ a IDENT(&& b) | c && e;
+ // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES-NOT: :[[@LINE-2]]:{{.*}}: note: FIX-IT applied suggested code changes
+
+ // insert `(` - GOOD
+ IDENT(a &&) b | c && e;
+ // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-FIXES: IDENT(a &&) (b || c) && e;
+
+ bool ab = false;
+ // insert ` = a` - BAD
+ CAT(a, b) &= b;
+ // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: use logical operator '&&' for boolean variable 'ab' instead of bitwise operator '&=' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES-NOT: :[[@LINE-2]]:{{.*}}: note: FIX-IT applied suggested code changes
+
+ // insert ` = a`- GOOD
+ b &= CAT(a, b);
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '&&' for boolean variable 'b' instead of bitwise operator '&=' [misc-bool-bitwise-operation]
+ // CHECK-FIXES: b = b && CAT(a, b);
+}
+
+void bad_in_macro_fixit() {
+ bool a = true, b = false;
+
+ // FIXME: implement fixit for all of these cases
+
+ a MY_OR b;
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ a MY_AND b;
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '&&' for boolean values instead of bitwise operator '&' [misc-bool-bitwise-operation]
+ a MY_OR_ASSIGN b;
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '||' for boolean variable 'a' instead of bitwise operator '|=' [misc-bool-bitwise-operation]
+ a MY_AND_ASSIGN b;
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '&&' for boolean variable 'a' instead of bitwise operator '&=' [misc-bool-bitwise-operation]
+ IDENT(a &= b);
+ // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use logical operator '&&' for boolean variable 'a' instead of bitwise operator '&=' [misc-bool-bitwise-operation]
+}
+
+template<typename T>
+void good_in_unreachable_template(T a, T b) {
+ a | b;
+ a & b;
+ a |= b;
+ a &= b;
+}
+
+template<typename T>
+int bad_in_template(T a, T b) {
+ bool c = false;
+ // FIXME: at least warning should be provided in these cases
+ // a | b;
+ // a & b;
+ // a |= b;
+ // a &= b;
+ // c &= a;
+ return 0;
+}
+
+template<typename T>
+int bad_in_template_lamnda_captured(T a, T b) {
+ [=] mutable {
+ bool c = false;
+ // FIXME: at least warning should be provided in these cases
+ // a | b;
+ // a & b;
+ // a |= b;
+ // b &= a;
+ }();
+ return 0;
+}
+
+int dummy = bad_in_template(true, false) + bad_in_template_lamnda_captured(false, true);
\ No newline at end of file
>From 0a1b47f8e3e6057fb8940a5873b6426ad6774697 Mon Sep 17 00:00:00 2001
From: Denis Mikhailov <denismikhaylov38 at gmail.com>
Date: Thu, 6 Nov 2025 19:59:01 +0300
Subject: [PATCH 02/28] Fix realworld case with unsigned flags
---
.../misc/BoolBitwiseOperationCheck.cpp | 72 ++++++-
.../bool-bitwise-operation-nontraditional.cpp | 43 ++--
...itwise-operation-not-only-bool-operand.cpp | 197 ++++++++++++++++++
.../checkers/misc/bool-bitwise-operation.cpp | 44 ++--
4 files changed, 311 insertions(+), 45 deletions(-)
create mode 100644 clang-tools-extra/test/clang-tidy/checkers/misc/bool-bitwise-operation-not-only-bool-operand.cpp
diff --git a/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.cpp b/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.cpp
index f37e1482c4a7d..6880322d85390 100644
--- a/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.cpp
+++ b/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.cpp
@@ -17,6 +17,68 @@ using namespace clang::ast_matchers;
namespace clang::tidy::misc {
+static const Stmt* ignoreParenExpr(const Stmt* S) {
+ while (const auto* PE = dyn_cast<ParenExpr>(S)) {
+ S = PE->getSubExpr();
+ }
+ return S;
+}
+
+template<typename R>
+static bool
+containsNodeIgnoringParenExpr(R&& children, const Stmt* Node) {
+ for (const Stmt* Child : children) {
+ if (ignoreParenExpr(Child) == Node) {
+ return true;
+ }
+ }
+ return false;
+}
+
+static bool isBooleanImplicitCastStmt(const Stmt* S) {
+ const auto* ICE = dyn_cast<ImplicitCastExpr>(S);
+ return ICE && ICE->getType()->isBooleanType();
+}
+
+namespace {
+AST_MATCHER(BinaryOperator, assignsToBoolean) {
+ auto Parents = Finder->getASTContext().getParents(Node);
+
+ for (const auto& Parent : Parents) {
+ // Check for Decl parents
+ if (const auto* D = Parent.template get<Decl>()) {
+ const Expr* InitExpr = nullptr;
+
+ if (const auto* VD = dyn_cast<VarDecl>(D)) {
+ InitExpr = VD->getInit();
+ } else if (const auto* FD = dyn_cast<FieldDecl>(D)) {
+ InitExpr = FD->getInClassInitializer();
+ } else if (const auto* NTTPD = dyn_cast<NonTypeTemplateParmDecl>(D)) {
+ if (NTTPD->getType()->isBooleanType()) {
+ return true;
+ }
+ }
+
+ if (InitExpr && isBooleanImplicitCastStmt(InitExpr)) {
+ return true;
+ }
+ }
+
+ // Check for Stmt parents
+ if (const auto* S = Parent.template get<Stmt>()) {
+ for (const Stmt* Child : S->children()) {
+ if (isBooleanImplicitCastStmt(Child) && containsNodeIgnoringParenExpr(Child->children(), &Node)) {
+ return true;
+ }
+ }
+ }
+ }
+
+ return false;
+}
+
+} // namespace
+
static const NamedDecl *
getLHSNamedDeclIfCompoundAssign(const BinaryOperator *BO) {
if (BO->isCompoundAssignmentOp()) {
@@ -27,6 +89,8 @@ getLHSNamedDeclIfCompoundAssign(const BinaryOperator *BO) {
return nullptr;
}
+constexpr std::array<llvm::StringRef, 4U> OperatorsNames{"|", "&", "|=", "&="};
+
constexpr std::array<std::pair<llvm::StringRef, llvm::StringRef>, 8U>
OperatorsTransformation{{{"|", "||"},
{"|=", "||"},
@@ -62,8 +126,12 @@ void BoolBitwiseOperationCheck::registerMatchers(MatchFinder *Finder) {
Finder->addMatcher(
binaryOperator(
unless(isExpansionInSystemHeader()),
- hasAnyOperatorName("|", "&", "|=", "&="),
- hasEitherOperand(expr(hasType(booleanType()))),
+ hasAnyOperatorName(OperatorsNames),
+ anyOf(
+ hasOperands(expr(hasType(booleanType())), expr(hasType(booleanType()))),
+ assignsToBoolean()
+ ),
+ // isBooleanLikeOperands(),
optionally(hasParent( // to simple implement transformations like
// `a&&b|c` -> `a&&(b||c)`
binaryOperator().bind("p"))))
diff --git a/clang-tools-extra/test/clang-tidy/checkers/misc/bool-bitwise-operation-nontraditional.cpp b/clang-tools-extra/test/clang-tidy/checkers/misc/bool-bitwise-operation-nontraditional.cpp
index d0700dbe309b5..59ee910fbfa5d 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/misc/bool-bitwise-operation-nontraditional.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/misc/bool-bitwise-operation-nontraditional.cpp
@@ -167,25 +167,26 @@ void bad_with_priors() {
void bad_with_priors2() {
bool a = false, b = true, c = true;
+ bool r;
a xor b bitand c;
// CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use logical operator '&&' for boolean values instead of bitwise operator '&' [misc-bool-bitwise-operation]
// CHECK-FIXES: a xor (b and c);
// braces added in the first change
- a bitor b bitand c;
- // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
- // CHECK-MESSAGES: :[[@LINE-2]]:15: warning: use logical operator '&&' for boolean values instead of bitwise operator '&' [misc-bool-bitwise-operation]
- // CHECK-FIXES: a or (b and c);
+ r = a bitor b bitand c;
+ // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-2]]:19: warning: use logical operator '&&' for boolean values instead of bitwise operator '&' [misc-bool-bitwise-operation]
+ // CHECK-FIXES: r = a or (b and c);
- b bitand c xor a;
- // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '&&' for boolean values instead of bitwise operator '&' [misc-bool-bitwise-operation]
- // CHECK-FIXES: (b and c) xor a;
+ r = b bitand c xor a;
+ // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: use logical operator '&&' for boolean values instead of bitwise operator '&' [misc-bool-bitwise-operation]
+ // CHECK-FIXES: r = (b and c) xor a;
// braces added in the first change
- b bitand c bitor a;
- // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '&&' for boolean values instead of bitwise operator '&' [misc-bool-bitwise-operation]
- // CHECK-MESSAGES: :[[@LINE-2]]:16: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
- // CHECK-FIXES: (b and c) or a;
+ r = b bitand c bitor a;
+ // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: use logical operator '&&' for boolean values instead of bitwise operator '&' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-2]]:20: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-FIXES: r = (b and c) or a;
}
template<typename T>
@@ -204,13 +205,13 @@ void bad_has_ancestor() {
// CHECK-FIXES: a xor ident(b and c or a);
a bitor ident(a ? b bitand c : c);
- // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
- // CHECK-MESSAGES: :[[@LINE-2]]:25: warning: use logical operator '&&' for boolean values instead of bitwise operator '&' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: use logical operator '&&' for boolean values instead of bitwise operator '&' [misc-bool-bitwise-operation]
// CHECK-FIXES: a bitor ident(a ? b and c : c);
}
void bad_with_priors_already_braced() {
bool a = false, b = true, c = true;
+ bool r;
a and (b bitor c);
// CHECK-MESSAGES: :[[@LINE-1]]:14: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
// CHECK-FIXES: a and (b or c);
@@ -228,19 +229,19 @@ void bad_with_priors_already_braced() {
// CHECK-MESSAGES: :[[@LINE-1]]:14: warning: use logical operator '&&' for boolean values instead of bitwise operator '&' [misc-bool-bitwise-operation]
// CHECK-FIXES: a xor (b and c);
- a bitor (b bitand c);
- // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
- // CHECK-MESSAGES: :[[@LINE-2]]:16: warning: use logical operator '&&' for boolean values instead of bitwise operator '&' [misc-bool-bitwise-operation]
- // CHECK-FIXES: a or (b and c);
+ r = a bitor (b bitand c);
+ // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-2]]:20: warning: use logical operator '&&' for boolean values instead of bitwise operator '&' [misc-bool-bitwise-operation]
+ // CHECK-FIXES: r = a or (b and c);
(b bitand c) xor a;
// CHECK-MESSAGES: :[[@LINE-1]]:8: warning: use logical operator '&&' for boolean values instead of bitwise operator '&' [misc-bool-bitwise-operation]
// CHECK-FIXES: (b and c) xor a;
- (b bitand c) bitor a;
- // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: use logical operator '&&' for boolean values instead of bitwise operator '&' [misc-bool-bitwise-operation]
- // CHECK-MESSAGES: :[[@LINE-2]]:18: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
- // CHECK-FIXES: (b and c) or a;
+ r = (b bitand c) bitor a;
+ // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: use logical operator '&&' for boolean values instead of bitwise operator '&' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-2]]:22: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-FIXES: r = (b and c) or a;
}
void bad_with_priors_compound() {
diff --git a/clang-tools-extra/test/clang-tidy/checkers/misc/bool-bitwise-operation-not-only-bool-operand.cpp b/clang-tools-extra/test/clang-tidy/checkers/misc/bool-bitwise-operation-not-only-bool-operand.cpp
new file mode 100644
index 0000000000000..6c3fd5ff0a140
--- /dev/null
+++ b/clang-tools-extra/test/clang-tidy/checkers/misc/bool-bitwise-operation-not-only-bool-operand.cpp
@@ -0,0 +1,197 @@
+// RUN: %check_clang_tidy %s misc-bool-bitwise-operation %t
+
+// got from clang/lib/APINotes/APINotesWriter.cpp
+
+void general(unsigned flags, bool value) {
+ (flags << 1) | value;
+ flags = (flags << 1) | value;
+}
+
+void take(bool value) {}
+
+// TODO: (flags << 1) | (flags << 2) | value
+
+template<bool bb = true | 1>
+// CHECK-MESSAGES: :[[@LINE-1]]:25: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+// CHECK-FIXES: template<bool bb = true || 1>
+void assign_to_boolean(unsigned flags, bool value) {
+ struct A { bool a = true | 1; };
+ // CHECK-MESSAGES: :[[@LINE-1]]:30: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-FIXES: struct A { bool a = true || 1; };
+ struct B { union { bool a = true | 1; }; };
+ // CHECK-MESSAGES: :[[@LINE-1]]:38: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-FIXES: struct B { union { bool a = true || 1; }; };
+ bool result = (flags << 1) | value;
+ // CHECK-MESSAGES: :[[@LINE-1]]:32: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-FIXES: bool result = (flags << 1) || value;
+ bool a = (flags << 2) | value,
+ // CHECK-MESSAGES: :[[@LINE-1]]:27: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-FIXES: bool a = (flags << 2) || value,
+ b = (flags << 4) | value,
+ // CHECK-MESSAGES: :[[@LINE-1]]:27: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-FIXES: b = (flags << 4) || value,
+ c = (flags << 8) | value;
+ // CHECK-MESSAGES: :[[@LINE-1]]:27: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-FIXES: c = (flags << 8) || value;
+ result = (flags << 1) | value;
+ // CHECK-MESSAGES: :[[@LINE-1]]:27: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-FIXES: result = (flags << 1) || value;
+ take((flags << 1) | value);
+ // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-FIXES: take((flags << 1) || value);
+}
+
+template<bool bb = (true | 1)>
+// CHECK-MESSAGES: :[[@LINE-1]]:26: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+// CHECK-FIXES: template<bool bb = (true || 1)>
+void assign_to_boolean_parens(unsigned flags, bool value) {
+ struct A { bool a = (true | 1); };
+ // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-FIXES: struct A { bool a = (true || 1); };
+ struct B { union { bool a = (true | 1); }; };
+ // CHECK-MESSAGES: :[[@LINE-1]]:39: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-FIXES: struct B { union { bool a = (true || 1); }; };
+ bool result = ((flags << 1) | value);
+ // CHECK-MESSAGES: :[[@LINE-1]]:33: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-FIXES: bool result = ((flags << 1) || value);
+ bool a = ((flags << 2) | value),
+ // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-FIXES: bool a = ((flags << 2) || value),
+ b = ((flags << 4) | value),
+ // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-FIXES: b = ((flags << 4) || value),
+ c = ((flags << 8) | value);
+ // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-FIXES: c = ((flags << 8) || value);
+ result = ((flags << 1) | value);
+ // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-FIXES: result = ((flags << 1) || value);
+ take(((flags << 1) | value));
+ // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-FIXES: take(((flags << 1) || value));
+}
+
+template<bool bb = ((true | 1))>
+// CHECK-MESSAGES: :[[@LINE-1]]:27: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+// CHECK-FIXES: template<bool bb = ((true || 1))>
+void assign_to_boolean_parens2(unsigned flags, bool value) {
+ struct A { bool a = ((true | 1)); };
+ // CHECK-MESSAGES: :[[@LINE-1]]:32: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-FIXES: struct A { bool a = ((true || 1)); };
+ struct B { union { bool a = ((true | 1)); }; };
+ // CHECK-MESSAGES: :[[@LINE-1]]:40: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-FIXES: struct B { union { bool a = ((true || 1)); }; };
+ bool result = (((flags << 1) | value));
+ // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-FIXES: bool result = (((flags << 1) || value));
+ bool a = (((flags << 2) | value)),
+ // CHECK-MESSAGES: :[[@LINE-1]]:29: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-FIXES: bool a = (((flags << 2) || value)),
+ b = (((flags << 4) | value)),
+ // CHECK-MESSAGES: :[[@LINE-1]]:29: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-FIXES: b = (((flags << 4) || value)),
+ c = (((flags << 8) | value));
+ // CHECK-MESSAGES: :[[@LINE-1]]:29: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-FIXES: c = (((flags << 8) || value));
+ result = (((flags << 1) | value));
+ // CHECK-MESSAGES: :[[@LINE-1]]:29: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-FIXES: result = (((flags << 1) || value));
+ take((((flags << 1) | value)));
+ // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-FIXES: take((((flags << 1) || value)));
+}
+
+// functional cast
+template<bool bb = bool(true | 1)>
+// CHECK-MESSAGES: :[[@LINE-1]]:30: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+// CHECK-FIXES: template<bool bb = bool(true || 1)>
+void assign_to_boolean_fcast(unsigned flags, bool value) {
+ struct A { bool a = bool(true | 1); };
+ // CHECK-MESSAGES: :[[@LINE-1]]:35: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-FIXES: struct A { bool a = bool(true || 1); };
+ struct B { union { bool a = bool(true | 1); }; };
+ // CHECK-MESSAGES: :[[@LINE-1]]:43: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-FIXES: struct B { union { bool a = bool(true || 1); }; };
+ bool result = bool((flags << 1) | value);
+ // CHECK-MESSAGES: :[[@LINE-1]]:37: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-FIXES: bool result = bool((flags << 1) || value);
+ bool a = bool((flags << 2) | value),
+ // CHECK-MESSAGES: :[[@LINE-1]]:32: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-FIXES: bool a = bool((flags << 2) || value),
+ b = bool((flags << 4) | value),
+ // CHECK-MESSAGES: :[[@LINE-1]]:32: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-FIXES: b = bool((flags << 4) || value),
+ c = bool((flags << 8) | value);
+ // CHECK-MESSAGES: :[[@LINE-1]]:32: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-FIXES: c = bool((flags << 8) || value);
+ result = bool((flags << 1) | value);
+ // CHECK-MESSAGES: :[[@LINE-1]]:32: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-FIXES: result = bool((flags << 1) || value);
+ take(bool((flags << 1) | value));
+ // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-FIXES: take(bool((flags << 1) || value));
+}
+
+// C-style cast
+template<bool bb = (bool)(true | 1)>
+// CHECK-MESSAGES: :[[@LINE-1]]:32: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+// CHECK-FIXES: template<bool bb = (bool)(true || 1)>
+void assign_to_boolean_ccast(unsigned flags, bool value) {
+ struct A { bool a = (bool)(true | 1); };
+ // CHECK-MESSAGES: :[[@LINE-1]]:37: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-FIXES: struct A { bool a = (bool)(true || 1); };
+ struct B { union { bool a = (bool)(true | 1); }; };
+ // CHECK-MESSAGES: :[[@LINE-1]]:45: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-FIXES: struct B { union { bool a = (bool)(true || 1); }; };
+ bool result = (bool)((flags << 1) | value);
+ // CHECK-MESSAGES: :[[@LINE-1]]:39: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-FIXES: bool result = (bool)((flags << 1) || value);
+ bool a = (bool)((flags << 2) | value),
+ // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-FIXES: bool a = (bool)((flags << 2) || value),
+ b = (bool)((flags << 4) | value),
+ // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-FIXES: b = (bool)((flags << 4) || value),
+ c = (bool)((flags << 8) | value);
+ // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-FIXES: c = (bool)((flags << 8) || value);
+ result = (bool)((flags << 1) | value);
+ // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-FIXES: result = (bool)((flags << 1) || value);
+ take(bool((flags << 1) | value));
+ // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-FIXES: take(bool((flags << 1) || value));
+}
+
+// static_cast
+template<bool bb = static_cast<bool>(true | 1)>
+// CHECK-MESSAGES: :[[@LINE-1]]:43: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+// CHECK-FIXES: template<bool bb = static_cast<bool>(true || 1)>
+void assign_to_boolean_scast(unsigned flags, bool value) {
+ struct A { bool a = static_cast<bool>(true | 1); };
+ // CHECK-MESSAGES: :[[@LINE-1]]:48: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-FIXES: struct A { bool a = static_cast<bool>(true || 1); };
+ struct B { union { bool a = static_cast<bool>(true | 1); }; };
+ // CHECK-MESSAGES: :[[@LINE-1]]:56: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-FIXES: struct B { union { bool a = static_cast<bool>(true || 1); }; };
+ bool result = static_cast<bool>((flags << 1) | value);
+ // CHECK-MESSAGES: :[[@LINE-1]]:50: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-FIXES: bool result = static_cast<bool>((flags << 1) || value);
+ bool a = static_cast<bool>((flags << 2) | value),
+ // CHECK-MESSAGES: :[[@LINE-1]]:45: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-FIXES: bool a = static_cast<bool>((flags << 2) || value),
+ b = static_cast<bool>((flags << 4) | value),
+ // CHECK-MESSAGES: :[[@LINE-1]]:45: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-FIXES: b = static_cast<bool>((flags << 4) || value),
+ c = static_cast<bool>((flags << 8) | value);
+ // CHECK-MESSAGES: :[[@LINE-1]]:45: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-FIXES: c = static_cast<bool>((flags << 8) || value);
+ result = static_cast<bool>((flags << 1) | value);
+ // CHECK-MESSAGES: :[[@LINE-1]]:45: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-FIXES: result = static_cast<bool>((flags << 1) || value);
+ take(static_cast<bool>((flags << 1) | value));
+ // CHECK-MESSAGES: :[[@LINE-1]]:41: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-FIXES: take(static_cast<bool>((flags << 1) || value));
+}
+
+
diff --git a/clang-tools-extra/test/clang-tidy/checkers/misc/bool-bitwise-operation.cpp b/clang-tools-extra/test/clang-tidy/checkers/misc/bool-bitwise-operation.cpp
index 86db240bb6efb..f58bd7c513ac9 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/misc/bool-bitwise-operation.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/misc/bool-bitwise-operation.cpp
@@ -167,25 +167,25 @@ void bad_with_priors() {
void bad_with_priors2() {
bool a = false, b = true, c = true;
+ bool r;
a ^ b & c;
// CHECK-MESSAGES: :[[@LINE-1]]:11: warning: use logical operator '&&' for boolean values instead of bitwise operator '&' [misc-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 '|' [misc-bool-bitwise-operation]
- // CHECK-MESSAGES: :[[@LINE-2]]:11: warning: use logical operator '&&' for boolean values instead of bitwise operator '&' [misc-bool-bitwise-operation]
- // CHECK-FIXES: a || (b && c);
+ r = a | b & c;
+ // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-2]]:15: warning: use logical operator '&&' for boolean values instead of bitwise operator '&' [misc-bool-bitwise-operation]
+ // CHECK-FIXES: r = a || (b && c);
- b & c ^ a;
- // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '&&' for boolean values instead of bitwise operator '&' [misc-bool-bitwise-operation]
- // CHECK-FIXES: (b && c) ^ a;
+ r = b & c ^ a;
+ // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: use logical operator '&&' for boolean values instead of bitwise operator '&' [misc-bool-bitwise-operation]
+ // CHECK-FIXES: r = (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 '&' [misc-bool-bitwise-operation]
- // CHECK-MESSAGES: :[[@LINE-2]]:11: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
- // CHECK-FIXES: (b && c) || a;
+ r = b & c | a;
+ // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: use logical operator '&&' for boolean values instead of bitwise operator '&' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-2]]:15: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-FIXES: r = (b && c) || a;
}
template<typename T>
@@ -204,13 +204,13 @@ void bad_has_ancestor() {
// 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 '|' [misc-bool-bitwise-operation]
- // CHECK-MESSAGES: :[[@LINE-2]]:21: warning: use logical operator '&&' for boolean values instead of bitwise operator '&' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:21: warning: use logical operator '&&' for boolean values instead of bitwise operator '&' [misc-bool-bitwise-operation]
// CHECK-FIXES: a | ident(a ? b && c : c);
}
void bad_with_priors_already_braced() {
bool a = false, b = true, c = true;
+ bool r;
a && (b | c);
// CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
// CHECK-FIXES: a && (b || c);
@@ -228,19 +228,19 @@ void bad_with_priors_already_braced() {
// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: use logical operator '&&' for boolean values instead of bitwise operator '&' [misc-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 '|' [misc-bool-bitwise-operation]
- // CHECK-MESSAGES: :[[@LINE-2]]:12: warning: use logical operator '&&' for boolean values instead of bitwise operator '&' [misc-bool-bitwise-operation]
- // CHECK-FIXES: a || (b && c);
+ r = a | (b & c);
+ // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-2]]:16: warning: use logical operator '&&' for boolean values instead of bitwise operator '&' [misc-bool-bitwise-operation]
+ // CHECK-FIXES: r = a || (b && c);
(b & c) ^ a;
// CHECK-MESSAGES: :[[@LINE-1]]:8: warning: use logical operator '&&' for boolean values instead of bitwise operator '&' [misc-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 '&' [misc-bool-bitwise-operation]
- // CHECK-MESSAGES: :[[@LINE-2]]:13: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
- // CHECK-FIXES: (b && c) || a;
+ r = (b & c) | a;
+ // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: use logical operator '&&' for boolean values instead of bitwise operator '&' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-2]]:17: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-FIXES: r = (b && c) || a;
}
void bad_with_priors_compound() {
>From 5bc7f73ca5522972e1680511010bc8a665cd8281 Mon Sep 17 00:00:00 2001
From: Denis Mikhailov <denismikhaylov38 at gmail.com>
Date: Fri, 7 Nov 2025 19:02:36 +0300
Subject: [PATCH 03/28] refactor a lot
---
.../misc/BoolBitwiseOperationCheck.cpp | 195 +++++++++---------
.../misc/BoolBitwiseOperationCheck.h | 9 +
.../bool-bitwise-operation-nontraditional.cpp | 13 ++
.../checkers/misc/bool-bitwise-operation.cpp | 13 ++
4 files changed, 137 insertions(+), 93 deletions(-)
diff --git a/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.cpp b/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.cpp
index 6880322d85390..1df170e5353f9 100644
--- a/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.cpp
+++ b/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.cpp
@@ -17,68 +17,46 @@ using namespace clang::ast_matchers;
namespace clang::tidy::misc {
-static const Stmt* ignoreParenExpr(const Stmt* S) {
- while (const auto* PE = dyn_cast<ParenExpr>(S)) {
- S = PE->getSubExpr();
- }
- return S;
-}
-
-template<typename R>
-static bool
-containsNodeIgnoringParenExpr(R&& children, const Stmt* Node) {
- for (const Stmt* Child : children) {
- if (ignoreParenExpr(Child) == Node) {
- return true;
+static const DynTypedNode *ignoreParensTowardsTheRoot(const DynTypedNode *N,
+ ASTContext *AC) {
+ if (const auto *S = N->get<Stmt>()) {
+ if (isa<ParenExpr>(S)) {
+ auto Parents = AC->getParents(*S);
+ for (const auto &Parent : Parents) {
+ return ignoreParensTowardsTheRoot(&Parent, AC);
+ }
}
}
- return false;
+ return N;
}
-static bool isBooleanImplicitCastStmt(const Stmt* S) {
- const auto* ICE = dyn_cast<ImplicitCastExpr>(S);
- return ICE && ICE->getType()->isBooleanType();
-}
+static bool assignsToBoolean(const BinaryOperator *BinOp, ASTContext *AC) {
+ TraversalKindScope RAII(*AC, TK_AsIs);
+ auto Parents = AC->getParents(*BinOp);
-namespace {
-AST_MATCHER(BinaryOperator, assignsToBoolean) {
- auto Parents = Finder->getASTContext().getParents(Node);
-
- for (const auto& Parent : Parents) {
- // Check for Decl parents
- if (const auto* D = Parent.template get<Decl>()) {
- const Expr* InitExpr = nullptr;
-
- if (const auto* VD = dyn_cast<VarDecl>(D)) {
- InitExpr = VD->getInit();
- } else if (const auto* FD = dyn_cast<FieldDecl>(D)) {
- InitExpr = FD->getInClassInitializer();
- } else if (const auto* NTTPD = dyn_cast<NonTypeTemplateParmDecl>(D)) {
+ for (const auto &Parent : Parents) {
+ const auto *ParentNoParen = ignoreParensTowardsTheRoot(&Parent, AC);
+ // Special handling for `template<bool bb=true|1>` cases
+ if (const auto *D = ParentNoParen->get<Decl>()) {
+ if (const auto *NTTPD = dyn_cast<NonTypeTemplateParmDecl>(D)) {
if (NTTPD->getType()->isBooleanType()) {
return true;
}
}
-
- if (InitExpr && isBooleanImplicitCastStmt(InitExpr)) {
- return true;
- }
}
-
- // Check for Stmt parents
- if (const auto* S = Parent.template get<Stmt>()) {
- for (const Stmt* Child : S->children()) {
- if (isBooleanImplicitCastStmt(Child) && containsNodeIgnoringParenExpr(Child->children(), &Node)) {
+
+ if (const auto *S = ParentNoParen->get<Stmt>()) {
+ if (const auto *ICE = dyn_cast<ImplicitCastExpr>(S)) {
+ if (ICE->getType()->isBooleanType()) {
return true;
}
}
}
}
-
+
return false;
}
-} // namespace
-
static const NamedDecl *
getLHSNamedDeclIfCompoundAssign(const BinaryOperator *BO) {
if (BO->isCompoundAssignmentOp()) {
@@ -89,8 +67,6 @@ getLHSNamedDeclIfCompoundAssign(const BinaryOperator *BO) {
return nullptr;
}
-constexpr std::array<llvm::StringRef, 4U> OperatorsNames{"|", "&", "|=", "&="};
-
constexpr std::array<std::pair<llvm::StringRef, llvm::StringRef>, 8U>
OperatorsTransformation{{{"|", "||"},
{"|=", "||"},
@@ -103,13 +79,32 @@ constexpr std::array<std::pair<llvm::StringRef, llvm::StringRef>, 8U>
static llvm::StringRef translate(llvm::StringRef Value) {
for (const auto &[Bitwise, Logical] : OperatorsTransformation) {
- if (Value == Bitwise)
+ if (Value == Bitwise) {
return Logical;
+ }
}
return {};
}
+static bool isBooleanBitwise(const BinaryOperator *BinOp, ASTContext *AC) {
+ for (const auto &[Bitwise, _] : OperatorsTransformation) {
+ if (BinOp->getOpcodeStr() == Bitwise) {
+ const bool hasBooleanOperands = llvm::all_of(
+ std::array{BinOp->getLHS(), BinOp->getRHS()}, [](const Expr *E) {
+ return E->IgnoreImpCasts()->getType().getTypePtr()->isBooleanType();
+ });
+ if (hasBooleanOperands) {
+ return true;
+ }
+ if (assignsToBoolean(BinOp, AC)) {
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
BoolBitwiseOperationCheck::BoolBitwiseOperationCheck(StringRef Name,
ClangTidyContext *Context)
: ClangTidyCheck(Name, Context),
@@ -124,52 +119,43 @@ void BoolBitwiseOperationCheck::storeOptions(
void BoolBitwiseOperationCheck::registerMatchers(MatchFinder *Finder) {
Finder->addMatcher(
- binaryOperator(
- unless(isExpansionInSystemHeader()),
- hasAnyOperatorName(OperatorsNames),
- anyOf(
- hasOperands(expr(hasType(booleanType())), expr(hasType(booleanType()))),
- assignsToBoolean()
- ),
- // isBooleanLikeOperands(),
- optionally(hasParent( // to simple implement transformations like
- // `a&&b|c` -> `a&&(b||c)`
- binaryOperator().bind("p"))))
- .bind("op"),
+ binaryOperator(unless(isExpansionInSystemHeader()),
+ unless(hasParent(binaryOperator())) // ignoring parenExpr
+ )
+ .bind("binOpRoot"),
this);
}
-void BoolBitwiseOperationCheck::check(const MatchFinder::MatchResult &Result) {
- const auto *MatchedExpr = Result.Nodes.getNodeAs<BinaryOperator>("op");
-
- auto DiagEmitter = [MatchedExpr, this] {
- const NamedDecl *ND = getLHSNamedDeclIfCompoundAssign(MatchedExpr);
- return diag(MatchedExpr->getOperatorLoc(),
+void BoolBitwiseOperationCheck::emitWarningAndChangeOperatorsIfPossible(
+ const BinaryOperator *BinOp, const BinaryOperator *ParentBinOp,
+ const clang::SourceManager &SM, clang::ASTContext &Ctx) {
+ auto DiagEmitter = [BinOp, this] {
+ const NamedDecl *ND = getLHSNamedDeclIfCompoundAssign(BinOp);
+ return diag(BinOp->getOperatorLoc(),
"use logical operator '%0' for boolean %select{variable "
"%2|values}1 instead of bitwise operator '%3'")
- << translate(MatchedExpr->getOpcodeStr()) << (ND == nullptr) << ND
- << MatchedExpr->getOpcodeStr();
+ << translate(BinOp->getOpcodeStr()) << (ND == nullptr) << ND
+ << BinOp->getOpcodeStr();
};
const bool HasVolatileOperand = llvm::any_of(
- std::array{MatchedExpr->getLHS(), MatchedExpr->getRHS()},
- [](const Expr *E) {
+ std::array{BinOp->getLHS(), BinOp->getRHS()}, [](const Expr *E) {
return E->IgnoreImpCasts()->getType().isVolatileQualified();
});
if (HasVolatileOperand)
return static_cast<void>(DiagEmitter());
- const bool HasSideEffects = MatchedExpr->getRHS()->HasSideEffects(
- *Result.Context, /*IncludePossibleEffects=*/!StrictMode);
+ const bool HasSideEffects = BinOp->getRHS()->HasSideEffects(
+ Ctx, /*IncludePossibleEffects=*/!StrictMode);
if (HasSideEffects)
return static_cast<void>(DiagEmitter());
- SourceLocation Loc = MatchedExpr->getOperatorLoc();
+ SourceLocation Loc = BinOp->getOperatorLoc();
if (Loc.isInvalid() || Loc.isMacroID())
return static_cast<void>(IgnoreMacros || DiagEmitter());
- Loc = Result.SourceManager->getSpellingLoc(Loc);
+ Loc = SM.getSpellingLoc(Loc);
if (Loc.isInvalid() || Loc.isMacroID())
return static_cast<void>(IgnoreMacros || DiagEmitter());
@@ -177,23 +163,23 @@ void BoolBitwiseOperationCheck::check(const MatchFinder::MatchResult &Result) {
if (TokenRange.isInvalid())
return static_cast<void>(IgnoreMacros || DiagEmitter());
- const StringRef FixSpelling = translate(Lexer::getSourceText(
- TokenRange, *Result.SourceManager, Result.Context->getLangOpts()));
+ const StringRef FixSpelling =
+ translate(Lexer::getSourceText(TokenRange, SM, Ctx.getLangOpts()));
if (FixSpelling.empty())
return static_cast<void>(DiagEmitter());
FixItHint InsertEqual;
- if (MatchedExpr->isCompoundAssignmentOp()) {
+ if (BinOp->isCompoundAssignmentOp()) {
const auto *DeclRefLHS =
- dyn_cast<DeclRefExpr>(MatchedExpr->getLHS()->IgnoreImpCasts());
+ dyn_cast<DeclRefExpr>(BinOp->getLHS()->IgnoreImpCasts());
if (!DeclRefLHS)
return static_cast<void>(DiagEmitter());
const SourceLocation LocLHS = DeclRefLHS->getEndLoc();
if (LocLHS.isInvalid() || LocLHS.isMacroID())
return static_cast<void>(IgnoreMacros || DiagEmitter());
- const SourceLocation InsertLoc = clang::Lexer::getLocForEndOfToken(
- LocLHS, 0, *Result.SourceManager, Result.Context->getLangOpts());
+ const SourceLocation InsertLoc =
+ clang::Lexer::getLocForEndOfToken(LocLHS, 0, SM, Ctx.getLangOpts());
if (InsertLoc.isInvalid() || InsertLoc.isMacroID())
return static_cast<void>(IgnoreMacros || DiagEmitter());
InsertEqual = FixItHint::CreateInsertion(
@@ -202,27 +188,25 @@ void BoolBitwiseOperationCheck::check(const MatchFinder::MatchResult &Result) {
auto ReplaceOperator = FixItHint::CreateReplacement(TokenRange, FixSpelling);
- const auto *Parent = Result.Nodes.getNodeAs<BinaryOperator>("p");
std::optional<BinaryOperatorKind> ParentOpcode;
- if (Parent)
- ParentOpcode = Parent->getOpcode();
+ if (ParentBinOp)
+ ParentOpcode = ParentBinOp->getOpcode();
- const auto *RHS =
- dyn_cast<BinaryOperator>(MatchedExpr->getRHS()->IgnoreImpCasts());
+ const auto *RHS = dyn_cast<BinaryOperator>(BinOp->getRHS()->IgnoreImpCasts());
std::optional<BinaryOperatorKind> RHSOpcode;
if (RHS)
RHSOpcode = RHS->getOpcode();
const Expr *SurroundedExpr = nullptr;
- if ((MatchedExpr->getOpcode() == BO_Or && ParentOpcode == BO_LAnd) ||
- (MatchedExpr->getOpcode() == BO_And &&
+ if ((BinOp->getOpcode() == BO_Or && ParentOpcode == BO_LAnd) ||
+ (BinOp->getOpcode() == BO_And &&
llvm::is_contained({BO_Xor, BO_Or}, ParentOpcode))) {
- const Expr *Side = Parent->getLHS()->IgnoreParenImpCasts() == MatchedExpr
- ? Parent->getLHS()
- : Parent->getRHS();
+ const Expr *Side = ParentBinOp->getLHS()->IgnoreParenImpCasts() == BinOp
+ ? ParentBinOp->getLHS()
+ : ParentBinOp->getRHS();
SurroundedExpr = Side->IgnoreImpCasts();
- assert(SurroundedExpr->IgnoreParens() == MatchedExpr);
- } else if (MatchedExpr->getOpcode() == BO_AndAssign && RHSOpcode == BO_LOr)
+ assert(SurroundedExpr->IgnoreParens() == BinOp);
+ } else if (BinOp->getOpcode() == BO_AndAssign && RHSOpcode == BO_LOr)
SurroundedExpr = RHS;
if (SurroundedExpr && isa<ParenExpr>(SurroundedExpr))
@@ -233,8 +217,7 @@ void BoolBitwiseOperationCheck::check(const MatchFinder::MatchResult &Result) {
if (SurroundedExpr) {
const SourceLocation InsertFirstLoc = SurroundedExpr->getBeginLoc();
const SourceLocation InsertSecondLoc = clang::Lexer::getLocForEndOfToken(
- SurroundedExpr->getEndLoc(), 0, *Result.SourceManager,
- Result.Context->getLangOpts());
+ SurroundedExpr->getEndLoc(), 0, SM, Ctx.getLangOpts());
if (InsertFirstLoc.isInvalid() || InsertFirstLoc.isMacroID() ||
InsertSecondLoc.isInvalid() || InsertSecondLoc.isMacroID())
return static_cast<void>(IgnoreMacros || DiagEmitter());
@@ -246,4 +229,30 @@ void BoolBitwiseOperationCheck::check(const MatchFinder::MatchResult &Result) {
<< InsertBrace2;
}
+void BoolBitwiseOperationCheck::visitBinaryTreesNode(
+ const BinaryOperator *BinOp, const BinaryOperator *ParentBinOp,
+ const clang::SourceManager &SM, clang::ASTContext &Ctx) {
+ if (!BinOp) {
+ return;
+ }
+
+ if (isBooleanBitwise(BinOp, &Ctx)) {
+ emitWarningAndChangeOperatorsIfPossible(BinOp, ParentBinOp, SM, Ctx);
+ }
+
+ visitBinaryTreesNode(
+ dyn_cast<BinaryOperator>(BinOp->getLHS()->IgnoreParenImpCasts()), BinOp,
+ SM, Ctx);
+ visitBinaryTreesNode(
+ dyn_cast<BinaryOperator>(BinOp->getRHS()->IgnoreParenImpCasts()), BinOp,
+ SM, Ctx);
+}
+
+void BoolBitwiseOperationCheck::check(const MatchFinder::MatchResult &Result) {
+ const auto *binOpRoot = Result.Nodes.getNodeAs<BinaryOperator>("binOpRoot");
+ const SourceManager &SM = *Result.SourceManager;
+ ASTContext &Ctx = *Result.Context;
+ visitBinaryTreesNode(binOpRoot, nullptr, SM, Ctx);
+}
+
} // namespace clang::tidy::misc
\ No newline at end of file
diff --git a/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.h b/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.h
index b1056e53c50c9..e1939afe772a7 100644
--- a/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.h
+++ b/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.h
@@ -32,6 +32,15 @@ class BoolBitwiseOperationCheck : public ClangTidyCheck {
return TK_IgnoreUnlessSpelledInSource;
}
+private:
+ void emitWarningAndChangeOperatorsIfPossible(
+ const BinaryOperator *BinOp, const BinaryOperator *ParentBinOp,
+ const clang::SourceManager &SM, clang::ASTContext &Ctx);
+ void visitBinaryTreesNode(const BinaryOperator *BinOp,
+ const BinaryOperator *ParentBinOp,
+ const clang::SourceManager &SM,
+ clang::ASTContext &Ctx);
+
private:
bool StrictMode;
bool IgnoreMacros;
diff --git a/clang-tools-extra/test/clang-tidy/checkers/misc/bool-bitwise-operation-nontraditional.cpp b/clang-tools-extra/test/clang-tidy/checkers/misc/bool-bitwise-operation-nontraditional.cpp
index 59ee910fbfa5d..4b50072849919 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/misc/bool-bitwise-operation-nontraditional.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/misc/bool-bitwise-operation-nontraditional.cpp
@@ -125,6 +125,9 @@ void bad_side_effects() {
void bad_side_effects_volatile() {
bool a = true;
volatile bool b = false;
+ bool c = true;
+ bool r;
+
a bitor b;
// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
// CHECK-MESSAGES-NOT: :[[@LINE-2]]:{{.*}}: note: FIX-IT applied suggested code changes
@@ -138,6 +141,16 @@ void bad_side_effects_volatile() {
a and_eq b;
// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '&&' for boolean variable 'a' instead of bitwise operator '&=' [misc-bool-bitwise-operation]
// CHECK-MESSAGES-NOT: :[[@LINE-2]]:{{.*}}: note: FIX-IT applied suggested code changes
+
+ r = (a bitor c) bitor b;
+ // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-2]]:21: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-FIXES: r = (a or c) bitor b;
+
+ r = a bitor c bitor b;
+ // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-2]]:19: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-FIXES: r = a or c bitor b;
}
void bad_with_priors() {
diff --git a/clang-tools-extra/test/clang-tidy/checkers/misc/bool-bitwise-operation.cpp b/clang-tools-extra/test/clang-tidy/checkers/misc/bool-bitwise-operation.cpp
index f58bd7c513ac9..56ca15b8d6729 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/misc/bool-bitwise-operation.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/misc/bool-bitwise-operation.cpp
@@ -125,6 +125,9 @@ void bad_side_effects() {
void bad_side_effects_volatile() {
bool a = true;
volatile bool b = false;
+ bool c = true;
+ bool r;
+
a | b;
// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
// CHECK-MESSAGES-NOT: :[[@LINE-2]]:{{.*}}: note: FIX-IT applied suggested code changes
@@ -138,6 +141,16 @@ void bad_side_effects_volatile() {
a &= b;
// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '&&' for boolean variable 'a' instead of bitwise operator '&=' [misc-bool-bitwise-operation]
// CHECK-MESSAGES-NOT: :[[@LINE-2]]:{{.*}}: note: FIX-IT applied suggested code changes
+
+ r = (a | c) | b;
+ // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-2]]:17: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-FIXES: r = (a || c) | b;
+
+ r = a | c | b;
+ // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-2]]:15: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-FIXES: r = a || c | b;
}
void bad_with_priors() {
>From 14dcf62ce58fe5e70ec70c9136711d3d5b1e4ae8 Mon Sep 17 00:00:00 2001
From: Denis Mikhailov <denismikhaylov38 at gmail.com>
Date: Fri, 7 Nov 2025 20:01:30 +0300
Subject: [PATCH 04/28] Implement more cases with unsigned flags
---
.../misc/BoolBitwiseOperationCheck.cpp | 18 +++---
.../misc/BoolBitwiseOperationCheck.h | 3 +-
...itwise-operation-not-only-bool-operand.cpp | 60 ++++++++++++++++++-
3 files changed, 71 insertions(+), 10 deletions(-)
diff --git a/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.cpp b/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.cpp
index 1df170e5353f9..c89050bd70d5d 100644
--- a/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.cpp
+++ b/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.cpp
@@ -87,7 +87,7 @@ static llvm::StringRef translate(llvm::StringRef Value) {
return {};
}
-static bool isBooleanBitwise(const BinaryOperator *BinOp, ASTContext *AC) {
+static bool isBooleanBitwise(const BinaryOperator *BinOp, ASTContext *AC, std::optional<bool>& rootAssignsToBoolean) {
for (const auto &[Bitwise, _] : OperatorsTransformation) {
if (BinOp->getOpcodeStr() == Bitwise) {
const bool hasBooleanOperands = llvm::all_of(
@@ -95,9 +95,11 @@ static bool isBooleanBitwise(const BinaryOperator *BinOp, ASTContext *AC) {
return E->IgnoreImpCasts()->getType().getTypePtr()->isBooleanType();
});
if (hasBooleanOperands) {
+ rootAssignsToBoolean = rootAssignsToBoolean.value_or(false);
return true;
}
- if (assignsToBoolean(BinOp, AC)) {
+ if (assignsToBoolean(BinOp, AC) || rootAssignsToBoolean.value_or(false)) {
+ rootAssignsToBoolean = rootAssignsToBoolean.value_or(true);
return true;
}
}
@@ -231,28 +233,30 @@ void BoolBitwiseOperationCheck::emitWarningAndChangeOperatorsIfPossible(
void BoolBitwiseOperationCheck::visitBinaryTreesNode(
const BinaryOperator *BinOp, const BinaryOperator *ParentBinOp,
- const clang::SourceManager &SM, clang::ASTContext &Ctx) {
+ const clang::SourceManager &SM, clang::ASTContext &Ctx,
+ std::optional<bool>& rootAssignsToBoolean) {
if (!BinOp) {
return;
}
- if (isBooleanBitwise(BinOp, &Ctx)) {
+ if (isBooleanBitwise(BinOp, &Ctx, rootAssignsToBoolean)) {
emitWarningAndChangeOperatorsIfPossible(BinOp, ParentBinOp, SM, Ctx);
}
visitBinaryTreesNode(
dyn_cast<BinaryOperator>(BinOp->getLHS()->IgnoreParenImpCasts()), BinOp,
- SM, Ctx);
+ SM, Ctx, rootAssignsToBoolean);
visitBinaryTreesNode(
dyn_cast<BinaryOperator>(BinOp->getRHS()->IgnoreParenImpCasts()), BinOp,
- SM, Ctx);
+ SM, Ctx, rootAssignsToBoolean);
}
void BoolBitwiseOperationCheck::check(const MatchFinder::MatchResult &Result) {
const auto *binOpRoot = Result.Nodes.getNodeAs<BinaryOperator>("binOpRoot");
const SourceManager &SM = *Result.SourceManager;
ASTContext &Ctx = *Result.Context;
- visitBinaryTreesNode(binOpRoot, nullptr, SM, Ctx);
+ std::optional<bool> rootAssignsToBoolean = std::nullopt;
+ visitBinaryTreesNode(binOpRoot, nullptr, SM, Ctx, rootAssignsToBoolean);
}
} // namespace clang::tidy::misc
\ No newline at end of file
diff --git a/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.h b/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.h
index e1939afe772a7..a04188027d3c2 100644
--- a/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.h
+++ b/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.h
@@ -39,7 +39,8 @@ class BoolBitwiseOperationCheck : public ClangTidyCheck {
void visitBinaryTreesNode(const BinaryOperator *BinOp,
const BinaryOperator *ParentBinOp,
const clang::SourceManager &SM,
- clang::ASTContext &Ctx);
+ clang::ASTContext &Ctx,
+ std::optional<bool>& rootAssignsToBoolean);
private:
bool StrictMode;
diff --git a/clang-tools-extra/test/clang-tidy/checkers/misc/bool-bitwise-operation-not-only-bool-operand.cpp b/clang-tools-extra/test/clang-tidy/checkers/misc/bool-bitwise-operation-not-only-bool-operand.cpp
index 6c3fd5ff0a140..364f23940b16e 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/misc/bool-bitwise-operation-not-only-bool-operand.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/misc/bool-bitwise-operation-not-only-bool-operand.cpp
@@ -5,11 +5,13 @@
void general(unsigned flags, bool value) {
(flags << 1) | value;
flags = (flags << 1) | value;
+ flags = (flags << 1) | (flags << 2) | value;
+ flags = (flags << 1) | (flags << 2) | (flags << 4) | value;
}
-void take(bool value) {}
+// TODO: compound operators
-// TODO: (flags << 1) | (flags << 2) | value
+void take(bool value) {}
template<bool bb = true | 1>
// CHECK-MESSAGES: :[[@LINE-1]]:25: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
@@ -39,6 +41,15 @@ void assign_to_boolean(unsigned flags, bool value) {
take((flags << 1) | value);
// CHECK-MESSAGES: :[[@LINE-1]]:23: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
// CHECK-FIXES: take((flags << 1) || value);
+ result = (flags << 1) | (flags << 2) | value;
+ // CHECK-MESSAGES: :[[@LINE-1]]:27: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-2]]:42: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-FIXES: result = (flags << 1) || (flags << 2) || value;
+ result = (flags << 1) | (flags << 2) | (flags << 4) | value;
+ // CHECK-MESSAGES: :[[@LINE-1]]:27: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-2]]:42: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-3]]:57: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-FIXES: result = (flags << 1) || (flags << 2) || (flags << 4) || value;
}
template<bool bb = (true | 1)>
@@ -69,6 +80,15 @@ void assign_to_boolean_parens(unsigned flags, bool value) {
take(((flags << 1) | value));
// CHECK-MESSAGES: :[[@LINE-1]]:24: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
// CHECK-FIXES: take(((flags << 1) || value));
+ result = ((flags << 1) | (flags << 2) | value);
+ // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-2]]:43: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-FIXES: result = ((flags << 1) || (flags << 2) || value);
+ result = ((flags << 1) | (flags << 2) | (flags << 4) | value);
+ // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-2]]:43: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-3]]:58: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-FIXES: result = ((flags << 1) || (flags << 2) || (flags << 4) || value);
}
template<bool bb = ((true | 1))>
@@ -99,6 +119,15 @@ void assign_to_boolean_parens2(unsigned flags, bool value) {
take((((flags << 1) | value)));
// CHECK-MESSAGES: :[[@LINE-1]]:25: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
// CHECK-FIXES: take((((flags << 1) || value)));
+ result = (((flags << 1) | (flags << 2) | value));
+ // CHECK-MESSAGES: :[[@LINE-1]]:29: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-2]]:44: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-FIXES: result = (((flags << 1) || (flags << 2) || value));
+ result = (((flags << 1) | (flags << 2) | (flags << 4) | value));
+ // CHECK-MESSAGES: :[[@LINE-1]]:29: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-2]]:44: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-3]]:59: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-FIXES: result = (((flags << 1) || (flags << 2) || (flags << 4) || value));
}
// functional cast
@@ -130,6 +159,15 @@ void assign_to_boolean_fcast(unsigned flags, bool value) {
take(bool((flags << 1) | value));
// CHECK-MESSAGES: :[[@LINE-1]]:28: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
// CHECK-FIXES: take(bool((flags << 1) || value));
+ result = bool((flags << 1) | (flags << 2) | value);
+ // CHECK-MESSAGES: :[[@LINE-1]]:32: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-2]]:47: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-FIXES: result = bool((flags << 1) || (flags << 2) || value);
+ result = bool((flags << 1) | (flags << 2) | (flags << 4) | value);
+ // CHECK-MESSAGES: :[[@LINE-1]]:32: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-2]]:47: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-3]]:62: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-FIXES: result = bool((flags << 1) || (flags << 2) || (flags << 4) || value);
}
// C-style cast
@@ -161,6 +199,15 @@ void assign_to_boolean_ccast(unsigned flags, bool value) {
take(bool((flags << 1) | value));
// CHECK-MESSAGES: :[[@LINE-1]]:28: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
// CHECK-FIXES: take(bool((flags << 1) || value));
+ result = (bool)((flags << 1) | (flags << 2) | value);
+ // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-2]]:49: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-FIXES: result = (bool)((flags << 1) || (flags << 2) || value);
+ result = (bool)((flags << 1) | (flags << 2) | (flags << 4) | value);
+ // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-2]]:49: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-3]]:64: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-FIXES: result = (bool)((flags << 1) || (flags << 2) || (flags << 4) || value);
}
// static_cast
@@ -192,6 +239,15 @@ void assign_to_boolean_scast(unsigned flags, bool value) {
take(static_cast<bool>((flags << 1) | value));
// CHECK-MESSAGES: :[[@LINE-1]]:41: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
// CHECK-FIXES: take(static_cast<bool>((flags << 1) || value));
+ result = static_cast<bool>((flags << 1) | (flags << 2) | value);
+ // CHECK-MESSAGES: :[[@LINE-1]]:45: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-2]]:60: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-FIXES: result = static_cast<bool>((flags << 1) || (flags << 2) || value);
+ result = static_cast<bool>((flags << 1) | (flags << 2) | (flags << 4) | value);
+ // CHECK-MESSAGES: :[[@LINE-1]]:45: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-2]]:60: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-3]]:75: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-FIXES: result = static_cast<bool>((flags << 1) || (flags << 2) || (flags << 4) || value);
}
>From 52844e3cc54061a7c8733dd3cdaa18405633740f Mon Sep 17 00:00:00 2001
From: Denis Mikhailov <denismikhaylov38 at gmail.com>
Date: Fri, 7 Nov 2025 20:01:54 +0300
Subject: [PATCH 05/28] No parentheses for single stmt ifs
---
.../clang-tidy/misc/BoolBitwiseOperationCheck.cpp | 15 +++++----------
1 file changed, 5 insertions(+), 10 deletions(-)
diff --git a/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.cpp b/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.cpp
index c89050bd70d5d..e0d412791f52c 100644
--- a/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.cpp
+++ b/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.cpp
@@ -39,17 +39,15 @@ static bool assignsToBoolean(const BinaryOperator *BinOp, ASTContext *AC) {
// Special handling for `template<bool bb=true|1>` cases
if (const auto *D = ParentNoParen->get<Decl>()) {
if (const auto *NTTPD = dyn_cast<NonTypeTemplateParmDecl>(D)) {
- if (NTTPD->getType()->isBooleanType()) {
+ if (NTTPD->getType()->isBooleanType())
return true;
- }
}
}
if (const auto *S = ParentNoParen->get<Stmt>()) {
if (const auto *ICE = dyn_cast<ImplicitCastExpr>(S)) {
- if (ICE->getType()->isBooleanType()) {
+ if (ICE->getType()->isBooleanType())
return true;
- }
}
}
}
@@ -79,9 +77,8 @@ constexpr std::array<std::pair<llvm::StringRef, llvm::StringRef>, 8U>
static llvm::StringRef translate(llvm::StringRef Value) {
for (const auto &[Bitwise, Logical] : OperatorsTransformation) {
- if (Value == Bitwise) {
+ if (Value == Bitwise)
return Logical;
- }
}
return {};
@@ -235,13 +232,11 @@ void BoolBitwiseOperationCheck::visitBinaryTreesNode(
const BinaryOperator *BinOp, const BinaryOperator *ParentBinOp,
const clang::SourceManager &SM, clang::ASTContext &Ctx,
std::optional<bool>& rootAssignsToBoolean) {
- if (!BinOp) {
+ if (!BinOp)
return;
- }
- if (isBooleanBitwise(BinOp, &Ctx, rootAssignsToBoolean)) {
+ if (isBooleanBitwise(BinOp, &Ctx, rootAssignsToBoolean))
emitWarningAndChangeOperatorsIfPossible(BinOp, ParentBinOp, SM, Ctx);
- }
visitBinaryTreesNode(
dyn_cast<BinaryOperator>(BinOp->getLHS()->IgnoreParenImpCasts()), BinOp,
>From d7ae3058c0e0a42c85dd5af8fff7a85b446830eb Mon Sep 17 00:00:00 2001
From: Denis Mikhailov <denismikhaylov38 at gmail.com>
Date: Sat, 8 Nov 2025 01:37:32 +0300
Subject: [PATCH 06/28] Important todo
---
.../misc/bool-bitwise-operation-not-only-bool-operand.cpp | 1 +
1 file changed, 1 insertion(+)
diff --git a/clang-tools-extra/test/clang-tidy/checkers/misc/bool-bitwise-operation-not-only-bool-operand.cpp b/clang-tools-extra/test/clang-tidy/checkers/misc/bool-bitwise-operation-not-only-bool-operand.cpp
index 364f23940b16e..56a3ba78f76ac 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/misc/bool-bitwise-operation-not-only-bool-operand.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/misc/bool-bitwise-operation-not-only-bool-operand.cpp
@@ -10,6 +10,7 @@ void general(unsigned flags, bool value) {
}
// TODO: compound operators
+// TODO: make sure parens dont spoil prior for compound operators
void take(bool value) {}
>From 793dc97ba640e3f70eb471db4fd2aa86450f61a8 Mon Sep 17 00:00:00 2001
From: Denis Mikhailov <denismikhaylov38 at gmail.com>
Date: Sat, 8 Nov 2025 14:28:42 +0300
Subject: [PATCH 07/28] Implement compound operator case with unsigned flags
---
.../clang-tidy/misc/BoolBitwiseOperationCheck.cpp | 9 +++++++++
...e-operation-not-only-bool-operand-compound.cpp | 15 +++++++++++++++
...ol-bitwise-operation-not-only-bool-operand.cpp | 4 ++--
3 files changed, 26 insertions(+), 2 deletions(-)
create mode 100644 clang-tools-extra/test/clang-tidy/checkers/misc/bool-bitwise-operation-not-only-bool-operand-compound.cpp
diff --git a/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.cpp b/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.cpp
index e0d412791f52c..725a9ebd0bdd2 100644
--- a/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.cpp
+++ b/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.cpp
@@ -13,6 +13,8 @@
#include <optional>
#include <utility>
+// TODO: change warning message
+
using namespace clang::ast_matchers;
namespace clang::tidy::misc {
@@ -99,6 +101,10 @@ static bool isBooleanBitwise(const BinaryOperator *BinOp, ASTContext *AC, std::o
rootAssignsToBoolean = rootAssignsToBoolean.value_or(true);
return true;
}
+ if (BinOp->isCompoundAssignmentOp() && BinOp->getLHS()->IgnoreImpCasts()->getType().getTypePtr()->isBooleanType()) {
+ rootAssignsToBoolean = rootAssignsToBoolean.value_or(true);
+ return true;
+ }
}
}
return false;
@@ -232,6 +238,7 @@ void BoolBitwiseOperationCheck::visitBinaryTreesNode(
const BinaryOperator *BinOp, const BinaryOperator *ParentBinOp,
const clang::SourceManager &SM, clang::ASTContext &Ctx,
std::optional<bool>& rootAssignsToBoolean) {
+ //llvm::outs() << "ENTER " << rootAssignsToBoolean << "\n";
if (!BinOp)
return;
@@ -244,6 +251,8 @@ void BoolBitwiseOperationCheck::visitBinaryTreesNode(
visitBinaryTreesNode(
dyn_cast<BinaryOperator>(BinOp->getRHS()->IgnoreParenImpCasts()), BinOp,
SM, Ctx, rootAssignsToBoolean);
+
+ //llvm::outs() << "LEAVE\n";
}
void BoolBitwiseOperationCheck::check(const MatchFinder::MatchResult &Result) {
diff --git a/clang-tools-extra/test/clang-tidy/checkers/misc/bool-bitwise-operation-not-only-bool-operand-compound.cpp b/clang-tools-extra/test/clang-tidy/checkers/misc/bool-bitwise-operation-not-only-bool-operand-compound.cpp
new file mode 100644
index 0000000000000..48f630392b76c
--- /dev/null
+++ b/clang-tools-extra/test/clang-tidy/checkers/misc/bool-bitwise-operation-not-only-bool-operand-compound.cpp
@@ -0,0 +1,15 @@
+// RUN: %check_clang_tidy %s misc-bool-bitwise-operation %t
+
+void general(unsigned flags, bool value) {
+ flags |= value;
+}
+
+void assign_to_boolean(unsigned flags, bool value) {
+ value |= flags << 1;
+ // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: use logical operator '||' for boolean variable 'value' instead of bitwise operator '|=' [misc-bool-bitwise-operation]
+ // CHECK-FIXES: value = value || flags << 1;
+ value |= (flags << 1) | (flags << 2);
+ // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: use logical operator '||' for boolean variable 'value' instead of bitwise operator '|=' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-2]]:27: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-FIXES: value = value || (flags << 1) || (flags << 2);
+}
diff --git a/clang-tools-extra/test/clang-tidy/checkers/misc/bool-bitwise-operation-not-only-bool-operand.cpp b/clang-tools-extra/test/clang-tidy/checkers/misc/bool-bitwise-operation-not-only-bool-operand.cpp
index 56a3ba78f76ac..7f447910ce406 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/misc/bool-bitwise-operation-not-only-bool-operand.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/misc/bool-bitwise-operation-not-only-bool-operand.cpp
@@ -1,6 +1,6 @@
// RUN: %check_clang_tidy %s misc-bool-bitwise-operation %t
-// got from clang/lib/APINotes/APINotesWriter.cpp
+// The case is taken from the real code in clang/lib/APINotes/APINotesWriter.cpp
void general(unsigned flags, bool value) {
(flags << 1) | value;
@@ -9,8 +9,8 @@ void general(unsigned flags, bool value) {
flags = (flags << 1) | (flags << 2) | (flags << 4) | value;
}
-// TODO: compound operators
// TODO: make sure parens dont spoil prior for compound operators
+// TODO: r = value |= flags << 1; (when r boolean, value unsigned)
void take(bool value) {}
>From 6e523d8b2021132b857195c5cd44fab83f343d47 Mon Sep 17 00:00:00 2001
From: Denis Mikhailov <denismikhaylov38 at gmail.com>
Date: Sat, 8 Nov 2025 15:03:05 +0300
Subject: [PATCH 08/28] review from 5chmidti
---
.../clang-tidy/misc/BoolBitwiseOperationCheck.cpp | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.cpp b/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.cpp
index 725a9ebd0bdd2..6778e7d5ec317 100644
--- a/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.cpp
+++ b/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.cpp
@@ -41,14 +41,14 @@ static bool assignsToBoolean(const BinaryOperator *BinOp, ASTContext *AC) {
// Special handling for `template<bool bb=true|1>` cases
if (const auto *D = ParentNoParen->get<Decl>()) {
if (const auto *NTTPD = dyn_cast<NonTypeTemplateParmDecl>(D)) {
- if (NTTPD->getType()->isBooleanType())
+ if (NTTPD->getType().getDesugaredType(*AC)->isBooleanType())
return true;
}
}
if (const auto *S = ParentNoParen->get<Stmt>()) {
if (const auto *ICE = dyn_cast<ImplicitCastExpr>(S)) {
- if (ICE->getType()->isBooleanType())
+ if (ICE->getType().getDesugaredType(*AC)->isBooleanType())
return true;
}
}
@@ -90,8 +90,8 @@ static bool isBooleanBitwise(const BinaryOperator *BinOp, ASTContext *AC, std::o
for (const auto &[Bitwise, _] : OperatorsTransformation) {
if (BinOp->getOpcodeStr() == Bitwise) {
const bool hasBooleanOperands = llvm::all_of(
- std::array{BinOp->getLHS(), BinOp->getRHS()}, [](const Expr *E) {
- return E->IgnoreImpCasts()->getType().getTypePtr()->isBooleanType();
+ std::array{BinOp->getLHS(), BinOp->getRHS()}, [&](const Expr *E) {
+ return E->IgnoreImpCasts()->getType().getDesugaredType(*AC)->isBooleanType();
});
if (hasBooleanOperands) {
rootAssignsToBoolean = rootAssignsToBoolean.value_or(false);
@@ -101,7 +101,7 @@ static bool isBooleanBitwise(const BinaryOperator *BinOp, ASTContext *AC, std::o
rootAssignsToBoolean = rootAssignsToBoolean.value_or(true);
return true;
}
- if (BinOp->isCompoundAssignmentOp() && BinOp->getLHS()->IgnoreImpCasts()->getType().getTypePtr()->isBooleanType()) {
+ if (BinOp->isCompoundAssignmentOp() && BinOp->getLHS()->IgnoreImpCasts()->getType().getDesugaredType(*AC)->isBooleanType()) {
rootAssignsToBoolean = rootAssignsToBoolean.value_or(true);
return true;
}
@@ -144,8 +144,8 @@ void BoolBitwiseOperationCheck::emitWarningAndChangeOperatorsIfPossible(
};
const bool HasVolatileOperand = llvm::any_of(
- std::array{BinOp->getLHS(), BinOp->getRHS()}, [](const Expr *E) {
- return E->IgnoreImpCasts()->getType().isVolatileQualified();
+ std::array{BinOp->getLHS(), BinOp->getRHS()}, [&](const Expr *E) {
+ return E->IgnoreImpCasts()->getType().getDesugaredType(Ctx).isVolatileQualified();
});
if (HasVolatileOperand)
return static_cast<void>(DiagEmitter());
>From 352d11840dc652bd1ac6178fd1e2e93cdada8dee Mon Sep 17 00:00:00 2001
From: Denis Mikhailov <denismikhaylov38 at gmail.com>
Date: Sat, 8 Nov 2025 19:20:58 +0300
Subject: [PATCH 09/28] Restore old unit-tests
---
.../misc/BoolBitwiseOperationCheck.cpp | 25 ++++++--
.../bool-bitwise-operation-nontraditional.cpp | 56 +++++++++---------
...eration-not-only-bool-operand-compound.cpp | 5 ++
...itwise-operation-not-only-bool-operand.cpp | 3 -
.../checkers/misc/bool-bitwise-operation.cpp | 57 +++++++++----------
5 files changed, 78 insertions(+), 68 deletions(-)
diff --git a/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.cpp b/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.cpp
index 6778e7d5ec317..204d650b4a552 100644
--- a/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.cpp
+++ b/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.cpp
@@ -87,13 +87,22 @@ static llvm::StringRef translate(llvm::StringRef Value) {
}
static bool isBooleanBitwise(const BinaryOperator *BinOp, ASTContext *AC, std::optional<bool>& rootAssignsToBoolean) {
+ if (!BinOp)
+ return false;
+
for (const auto &[Bitwise, _] : OperatorsTransformation) {
if (BinOp->getOpcodeStr() == Bitwise) {
- const bool hasBooleanOperands = llvm::all_of(
- std::array{BinOp->getLHS(), BinOp->getRHS()}, [&](const Expr *E) {
- return E->IgnoreImpCasts()->getType().getDesugaredType(*AC)->isBooleanType();
- });
- if (hasBooleanOperands) {
+ const bool lhsBoolean = BinOp->getLHS()
+ ->IgnoreImpCasts()
+ ->getType()
+ .getDesugaredType(*AC)
+ ->isBooleanType();
+ const bool rhsBoolean = BinOp->getRHS()
+ ->IgnoreImpCasts()
+ ->getType()
+ .getDesugaredType(*AC)
+ ->isBooleanType();
+ if (lhsBoolean && rhsBoolean) {
rootAssignsToBoolean = rootAssignsToBoolean.value_or(false);
return true;
}
@@ -101,10 +110,14 @@ static bool isBooleanBitwise(const BinaryOperator *BinOp, ASTContext *AC, std::o
rootAssignsToBoolean = rootAssignsToBoolean.value_or(true);
return true;
}
- if (BinOp->isCompoundAssignmentOp() && BinOp->getLHS()->IgnoreImpCasts()->getType().getDesugaredType(*AC)->isBooleanType()) {
+ if (BinOp->isCompoundAssignmentOp() && lhsBoolean) {
rootAssignsToBoolean = rootAssignsToBoolean.value_or(true);
return true;
}
+ if (std::optional<bool> DummyFlag = false; (lhsBoolean || isBooleanBitwise(dyn_cast<BinaryOperator>(BinOp->getLHS()->IgnoreParenImpCasts()), AC, DummyFlag)) && (rhsBoolean || isBooleanBitwise(dyn_cast<BinaryOperator>(BinOp->getRHS()->IgnoreParenImpCasts()), AC, DummyFlag))) {
+ rootAssignsToBoolean = rootAssignsToBoolean.value_or(false);
+ return true;
+ }
}
}
return false;
diff --git a/clang-tools-extra/test/clang-tidy/checkers/misc/bool-bitwise-operation-nontraditional.cpp b/clang-tools-extra/test/clang-tidy/checkers/misc/bool-bitwise-operation-nontraditional.cpp
index 4b50072849919..14b8dcf1ac0ce 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/misc/bool-bitwise-operation-nontraditional.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/misc/bool-bitwise-operation-nontraditional.cpp
@@ -126,7 +126,6 @@ void bad_side_effects_volatile() {
bool a = true;
volatile bool b = false;
bool c = true;
- bool r;
a bitor b;
// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
@@ -142,15 +141,15 @@ void bad_side_effects_volatile() {
// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '&&' for boolean variable 'a' instead of bitwise operator '&=' [misc-bool-bitwise-operation]
// CHECK-MESSAGES-NOT: :[[@LINE-2]]:{{.*}}: note: FIX-IT applied suggested code changes
- r = (a bitor c) bitor b;
- // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
- // CHECK-MESSAGES: :[[@LINE-2]]:21: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
- // CHECK-FIXES: r = (a or c) bitor b;
+ (a bitor c) bitor b;
+ // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-2]]:17: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-FIXES: (a or c) bitor b;
- r = a bitor c bitor b;
- // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
- // CHECK-MESSAGES: :[[@LINE-2]]:19: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
- // CHECK-FIXES: r = a or c bitor b;
+ a bitor c bitor b;
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-2]]:15: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-FIXES: a or c bitor b;
}
void bad_with_priors() {
@@ -186,20 +185,20 @@ void bad_with_priors2() {
// CHECK-FIXES: a xor (b and c);
// braces added in the first change
- r = a bitor b bitand c;
- // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
- // CHECK-MESSAGES: :[[@LINE-2]]:19: warning: use logical operator '&&' for boolean values instead of bitwise operator '&' [misc-bool-bitwise-operation]
- // CHECK-FIXES: r = a or (b and c);
+ a bitor b bitand c;
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-2]]:15: warning: use logical operator '&&' for boolean values instead of bitwise operator '&' [misc-bool-bitwise-operation]
+ // CHECK-FIXES: a or (b and c);
- r = b bitand c xor a;
- // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: use logical operator '&&' for boolean values instead of bitwise operator '&' [misc-bool-bitwise-operation]
- // CHECK-FIXES: r = (b and c) xor a;
+ b bitand c xor a;
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '&&' for boolean values instead of bitwise operator '&' [misc-bool-bitwise-operation]
+ // CHECK-FIXES: (b and c) xor a;
// braces added in the first change
- r = b bitand c bitor a;
- // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: use logical operator '&&' for boolean values instead of bitwise operator '&' [misc-bool-bitwise-operation]
- // CHECK-MESSAGES: :[[@LINE-2]]:20: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
- // CHECK-FIXES: r = (b and c) or a;
+ b bitand c bitor a;
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '&&' for boolean values instead of bitwise operator '&' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-2]]:16: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-FIXES: (b and c) or a;
}
template<typename T>
@@ -224,7 +223,6 @@ void bad_has_ancestor() {
void bad_with_priors_already_braced() {
bool a = false, b = true, c = true;
- bool r;
a and (b bitor c);
// CHECK-MESSAGES: :[[@LINE-1]]:14: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
// CHECK-FIXES: a and (b or c);
@@ -242,19 +240,19 @@ void bad_with_priors_already_braced() {
// CHECK-MESSAGES: :[[@LINE-1]]:14: warning: use logical operator '&&' for boolean values instead of bitwise operator '&' [misc-bool-bitwise-operation]
// CHECK-FIXES: a xor (b and c);
- r = a bitor (b bitand c);
- // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
- // CHECK-MESSAGES: :[[@LINE-2]]:20: warning: use logical operator '&&' for boolean values instead of bitwise operator '&' [misc-bool-bitwise-operation]
- // CHECK-FIXES: r = a or (b and c);
+ a bitor (b bitand c);
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-2]]:16: warning: use logical operator '&&' for boolean values instead of bitwise operator '&' [misc-bool-bitwise-operation]
+ // CHECK-FIXES: a or (b and c);
(b bitand c) xor a;
// CHECK-MESSAGES: :[[@LINE-1]]:8: warning: use logical operator '&&' for boolean values instead of bitwise operator '&' [misc-bool-bitwise-operation]
// CHECK-FIXES: (b and c) xor a;
- r = (b bitand c) bitor a;
- // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: use logical operator '&&' for boolean values instead of bitwise operator '&' [misc-bool-bitwise-operation]
- // CHECK-MESSAGES: :[[@LINE-2]]:22: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
- // CHECK-FIXES: r = (b and c) or a;
+ (b bitand c) bitor a;
+ // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: use logical operator '&&' for boolean values instead of bitwise operator '&' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-2]]:18: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-FIXES: (b and c) or a;
}
void bad_with_priors_compound() {
diff --git a/clang-tools-extra/test/clang-tidy/checkers/misc/bool-bitwise-operation-not-only-bool-operand-compound.cpp b/clang-tools-extra/test/clang-tidy/checkers/misc/bool-bitwise-operation-not-only-bool-operand-compound.cpp
index 48f630392b76c..ec9f536afe0a8 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/misc/bool-bitwise-operation-not-only-bool-operand-compound.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/misc/bool-bitwise-operation-not-only-bool-operand-compound.cpp
@@ -2,6 +2,11 @@
void general(unsigned flags, bool value) {
flags |= value;
+
+ unsigned mask = 0b1100;
+ bool result = flags &= mask;
+ auto result2 = flags &= mask;
+ result = flags |= flags << 1;
}
void assign_to_boolean(unsigned flags, bool value) {
diff --git a/clang-tools-extra/test/clang-tidy/checkers/misc/bool-bitwise-operation-not-only-bool-operand.cpp b/clang-tools-extra/test/clang-tidy/checkers/misc/bool-bitwise-operation-not-only-bool-operand.cpp
index 7f447910ce406..603d49c7b24e6 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/misc/bool-bitwise-operation-not-only-bool-operand.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/misc/bool-bitwise-operation-not-only-bool-operand.cpp
@@ -9,9 +9,6 @@ void general(unsigned flags, bool value) {
flags = (flags << 1) | (flags << 2) | (flags << 4) | value;
}
-// TODO: make sure parens dont spoil prior for compound operators
-// TODO: r = value |= flags << 1; (when r boolean, value unsigned)
-
void take(bool value) {}
template<bool bb = true | 1>
diff --git a/clang-tools-extra/test/clang-tidy/checkers/misc/bool-bitwise-operation.cpp b/clang-tools-extra/test/clang-tidy/checkers/misc/bool-bitwise-operation.cpp
index 56ca15b8d6729..2cc725cb8781f 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/misc/bool-bitwise-operation.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/misc/bool-bitwise-operation.cpp
@@ -126,7 +126,6 @@ void bad_side_effects_volatile() {
bool a = true;
volatile bool b = false;
bool c = true;
- bool r;
a | b;
// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
@@ -142,15 +141,15 @@ void bad_side_effects_volatile() {
// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '&&' for boolean variable 'a' instead of bitwise operator '&=' [misc-bool-bitwise-operation]
// CHECK-MESSAGES-NOT: :[[@LINE-2]]:{{.*}}: note: FIX-IT applied suggested code changes
- r = (a | c) | b;
- // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
- // CHECK-MESSAGES: :[[@LINE-2]]:17: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
- // CHECK-FIXES: r = (a || c) | b;
+ (a | c) | b;
+ // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-2]]:13: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-FIXES: (a || c) | b;
- r = a | c | b;
- // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
- // CHECK-MESSAGES: :[[@LINE-2]]:15: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
- // CHECK-FIXES: r = a || c | b;
+ a | c | b;
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-2]]:11: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-FIXES: a || c | b;
}
void bad_with_priors() {
@@ -180,25 +179,24 @@ void bad_with_priors() {
void bad_with_priors2() {
bool a = false, b = true, c = true;
- bool r;
a ^ b & c;
// CHECK-MESSAGES: :[[@LINE-1]]:11: warning: use logical operator '&&' for boolean values instead of bitwise operator '&' [misc-bool-bitwise-operation]
// CHECK-FIXES: a ^ (b && c);
// braces added in the first change
- r = a | b & c;
- // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
- // CHECK-MESSAGES: :[[@LINE-2]]:15: warning: use logical operator '&&' for boolean values instead of bitwise operator '&' [misc-bool-bitwise-operation]
- // CHECK-FIXES: r = a || (b && c);
+ a | b & c;
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-2]]:11: warning: use logical operator '&&' for boolean values instead of bitwise operator '&' [misc-bool-bitwise-operation]
+ // CHECK-FIXES: a || (b && c);
- r = b & c ^ a;
- // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: use logical operator '&&' for boolean values instead of bitwise operator '&' [misc-bool-bitwise-operation]
- // CHECK-FIXES: r = (b && c) ^ a;
+ b & c ^ a;
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '&&' for boolean values instead of bitwise operator '&' [misc-bool-bitwise-operation]
+ // CHECK-FIXES: (b && c) ^ a;
// braces added in the first change
- r = b & c | a;
- // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: use logical operator '&&' for boolean values instead of bitwise operator '&' [misc-bool-bitwise-operation]
- // CHECK-MESSAGES: :[[@LINE-2]]:15: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
- // CHECK-FIXES: r = (b && c) || a;
+ b & c | a;
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '&&' for boolean values instead of bitwise operator '&' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-2]]:11: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-FIXES: (b && c) || a;
}
template<typename T>
@@ -223,7 +221,6 @@ void bad_has_ancestor() {
void bad_with_priors_already_braced() {
bool a = false, b = true, c = true;
- bool r;
a && (b | c);
// CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
// CHECK-FIXES: a && (b || c);
@@ -241,19 +238,19 @@ void bad_with_priors_already_braced() {
// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: use logical operator '&&' for boolean values instead of bitwise operator '&' [misc-bool-bitwise-operation]
// CHECK-FIXES: a ^ (b && c);
- r = a | (b & c);
- // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
- // CHECK-MESSAGES: :[[@LINE-2]]:16: warning: use logical operator '&&' for boolean values instead of bitwise operator '&' [misc-bool-bitwise-operation]
- // CHECK-FIXES: r = a || (b && c);
+ a | (b & c);
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-2]]:12: warning: use logical operator '&&' for boolean values instead of bitwise operator '&' [misc-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 '&' [misc-bool-bitwise-operation]
// CHECK-FIXES: (b && c) ^ a;
- r = (b & c) | a;
- // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: use logical operator '&&' for boolean values instead of bitwise operator '&' [misc-bool-bitwise-operation]
- // CHECK-MESSAGES: :[[@LINE-2]]:17: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
- // CHECK-FIXES: r = (b && c) || a;
+ (b & c) | a;
+ // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: use logical operator '&&' for boolean values instead of bitwise operator '&' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-2]]:13: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-FIXES: (b && c) || a;
}
void bad_with_priors_compound() {
>From 0d4aa3bb269a9ece5c44a531b15c5887c06476c4 Mon Sep 17 00:00:00 2001
From: Denis Mikhailov <denismikhaylov38 at gmail.com>
Date: Sat, 8 Nov 2025 19:51:01 +0300
Subject: [PATCH 10/28] Refactor && Change warning mesage
---
.../misc/BoolBitwiseOperationCheck.cpp | 77 ++++----
...-operation-change-possible-side-effect.cpp | 8 +-
.../bool-bitwise-operation-ignore-macros.cpp | 10 +-
.../bool-bitwise-operation-nontraditional.cpp | 122 ++++++-------
...eration-not-only-bool-operand-compound.cpp | 2 +-
...itwise-operation-not-only-bool-operand.cpp | 168 +++++++++---------
.../checkers/misc/bool-bitwise-operation.c | 4 +-
.../checkers/misc/bool-bitwise-operation.cpp | 122 ++++++-------
8 files changed, 261 insertions(+), 252 deletions(-)
diff --git a/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.cpp b/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.cpp
index 204d650b4a552..a37935ea3a0d0 100644
--- a/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.cpp
+++ b/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.cpp
@@ -13,8 +13,6 @@
#include <optional>
#include <utility>
-// TODO: change warning message
-
using namespace clang::ast_matchers;
namespace clang::tidy::misc {
@@ -86,37 +84,48 @@ static llvm::StringRef translate(llvm::StringRef Value) {
return {};
}
-static bool isBooleanBitwise(const BinaryOperator *BinOp, ASTContext *AC, std::optional<bool>& rootAssignsToBoolean) {
+static bool isBooleanBitwise(const BinaryOperator *BinOp, ASTContext *AC,
+ std::optional<bool> &rootAssignsToBoolean) {
if (!BinOp)
return false;
for (const auto &[Bitwise, _] : OperatorsTransformation) {
if (BinOp->getOpcodeStr() == Bitwise) {
- const bool lhsBoolean = BinOp->getLHS()
- ->IgnoreImpCasts()
- ->getType()
- .getDesugaredType(*AC)
- ->isBooleanType();
- const bool rhsBoolean = BinOp->getRHS()
- ->IgnoreImpCasts()
- ->getType()
- .getDesugaredType(*AC)
- ->isBooleanType();
- if (lhsBoolean && rhsBoolean) {
- rootAssignsToBoolean = rootAssignsToBoolean.value_or(false);
- return true;
- }
- if (assignsToBoolean(BinOp, AC) || rootAssignsToBoolean.value_or(false)) {
- rootAssignsToBoolean = rootAssignsToBoolean.value_or(true);
- return true;
- }
- if (BinOp->isCompoundAssignmentOp() && lhsBoolean) {
- rootAssignsToBoolean = rootAssignsToBoolean.value_or(true);
- return true;
- }
- if (std::optional<bool> DummyFlag = false; (lhsBoolean || isBooleanBitwise(dyn_cast<BinaryOperator>(BinOp->getLHS()->IgnoreParenImpCasts()), AC, DummyFlag)) && (rhsBoolean || isBooleanBitwise(dyn_cast<BinaryOperator>(BinOp->getRHS()->IgnoreParenImpCasts()), AC, DummyFlag))) {
- rootAssignsToBoolean = rootAssignsToBoolean.value_or(false);
- return true;
+ bool lhsBoolean = BinOp->getLHS()
+ ->IgnoreImpCasts()
+ ->getType()
+ .getDesugaredType(*AC)
+ ->isBooleanType();
+ bool rhsBoolean = BinOp->getRHS()
+ ->IgnoreImpCasts()
+ ->getType()
+ .getDesugaredType(*AC)
+ ->isBooleanType();
+ for (int i = 0; i < 2; ++i) {
+ if (lhsBoolean && rhsBoolean) {
+ rootAssignsToBoolean = rootAssignsToBoolean.value_or(false);
+ return true;
+ }
+ if (assignsToBoolean(BinOp, AC) ||
+ rootAssignsToBoolean.value_or(false)) {
+ rootAssignsToBoolean = rootAssignsToBoolean.value_or(true);
+ return true;
+ }
+ if (BinOp->isCompoundAssignmentOp() && lhsBoolean) {
+ rootAssignsToBoolean = rootAssignsToBoolean.value_or(true);
+ return true;
+ }
+ std::optional<bool> DummyFlag = false;
+ lhsBoolean =
+ lhsBoolean ||
+ isBooleanBitwise(dyn_cast<BinaryOperator>(
+ BinOp->getLHS()->IgnoreParenImpCasts()),
+ AC, DummyFlag);
+ rhsBoolean =
+ rhsBoolean ||
+ isBooleanBitwise(dyn_cast<BinaryOperator>(
+ BinOp->getRHS()->IgnoreParenImpCasts()),
+ AC, DummyFlag);
}
}
}
@@ -151,14 +160,17 @@ void BoolBitwiseOperationCheck::emitWarningAndChangeOperatorsIfPossible(
const NamedDecl *ND = getLHSNamedDeclIfCompoundAssign(BinOp);
return diag(BinOp->getOperatorLoc(),
"use logical operator '%0' for boolean %select{variable "
- "%2|values}1 instead of bitwise operator '%3'")
+ "%2|semantics}1 instead of bitwise operator '%3'")
<< translate(BinOp->getOpcodeStr()) << (ND == nullptr) << ND
<< BinOp->getOpcodeStr();
};
const bool HasVolatileOperand = llvm::any_of(
std::array{BinOp->getLHS(), BinOp->getRHS()}, [&](const Expr *E) {
- return E->IgnoreImpCasts()->getType().getDesugaredType(Ctx).isVolatileQualified();
+ return E->IgnoreImpCasts()
+ ->getType()
+ .getDesugaredType(Ctx)
+ .isVolatileQualified();
});
if (HasVolatileOperand)
return static_cast<void>(DiagEmitter());
@@ -250,8 +262,7 @@ void BoolBitwiseOperationCheck::emitWarningAndChangeOperatorsIfPossible(
void BoolBitwiseOperationCheck::visitBinaryTreesNode(
const BinaryOperator *BinOp, const BinaryOperator *ParentBinOp,
const clang::SourceManager &SM, clang::ASTContext &Ctx,
- std::optional<bool>& rootAssignsToBoolean) {
- //llvm::outs() << "ENTER " << rootAssignsToBoolean << "\n";
+ std::optional<bool> &rootAssignsToBoolean) {
if (!BinOp)
return;
@@ -264,8 +275,6 @@ void BoolBitwiseOperationCheck::visitBinaryTreesNode(
visitBinaryTreesNode(
dyn_cast<BinaryOperator>(BinOp->getRHS()->IgnoreParenImpCasts()), BinOp,
SM, Ctx, rootAssignsToBoolean);
-
- //llvm::outs() << "LEAVE\n";
}
void BoolBitwiseOperationCheck::check(const MatchFinder::MatchResult &Result) {
diff --git a/clang-tools-extra/test/clang-tidy/checkers/misc/bool-bitwise-operation-change-possible-side-effect.cpp b/clang-tools-extra/test/clang-tidy/checkers/misc/bool-bitwise-operation-change-possible-side-effect.cpp
index a92d32f55701f..d58f3ecd836fd 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/misc/bool-bitwise-operation-change-possible-side-effect.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/misc/bool-bitwise-operation-change-possible-side-effect.cpp
@@ -8,11 +8,11 @@ void bad_possible_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 '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
// CHECK-FIXES: a || function_with_possible_side_effects();
a & function_with_possible_side_effects();
- // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '&&' for boolean values instead of bitwise operator '&' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '&&' for boolean semantics instead of bitwise operator '&' [misc-bool-bitwise-operation]
// CHECK-FIXES: a && function_with_possible_side_effects();
a |= function_with_possible_side_effects();
@@ -47,11 +47,11 @@ void bad_definitely_side_effects() {
int acc = 0;
a | (acc++, b);
- // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
// CHECK-MESSAGES-NOT: :[[@LINE-2]]:{{.*}}: note: FIX-IT applied suggested code changes
a & (acc++, b);
- // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '&&' for boolean values instead of bitwise operator '&' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '&&' for boolean semantics instead of bitwise operator '&' [misc-bool-bitwise-operation]
// CHECK-MESSAGES-NOT: :[[@LINE-2]]:{{.*}}: note: FIX-IT applied suggested code changes
a |= (acc++, b);
diff --git a/clang-tools-extra/test/clang-tidy/checkers/misc/bool-bitwise-operation-ignore-macros.cpp b/clang-tools-extra/test/clang-tidy/checkers/misc/bool-bitwise-operation-ignore-macros.cpp
index 5b879063bae6b..43faddcc3beea 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/misc/bool-bitwise-operation-ignore-macros.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/misc/bool-bitwise-operation-ignore-macros.cpp
@@ -16,13 +16,13 @@ void bad_in_macro() {
// change operator - GOOD
IDENT(a) | b;
- // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
// CHECK-FIXES: IDENT(a) || b;
a & IDENT(b);
- // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '&&' for boolean values instead of bitwise operator '&' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '&&' for boolean semantics instead of bitwise operator '&' [misc-bool-bitwise-operation]
// CHECK-FIXES: a && IDENT(b);
IDENT(a) & IDENT(b);
- // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: use logical operator '&&' for boolean values instead of bitwise operator '&' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: use logical operator '&&' for boolean semantics instead of bitwise operator '&' [misc-bool-bitwise-operation]
// CHECK-FIXES: IDENT(a) && IDENT(b);
// insert `)` - BAD
@@ -31,7 +31,7 @@ void bad_in_macro() {
// insert `)` - GOOD
a && b | c IDENT(&& e);
- // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
// CHECK-FIXES: a && (b || c) IDENT(&& e);
// insert `(` - BAD
@@ -39,7 +39,7 @@ void bad_in_macro() {
// insert `(` - GOOD
IDENT(a &&) b | c && e;
- // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
// CHECK-FIXES: IDENT(a &&) (b || c) && e;
bool ab = false;
diff --git a/clang-tools-extra/test/clang-tidy/checkers/misc/bool-bitwise-operation-nontraditional.cpp b/clang-tools-extra/test/clang-tidy/checkers/misc/bool-bitwise-operation-nontraditional.cpp
index 14b8dcf1ac0ce..314f2087dcf3a 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/misc/bool-bitwise-operation-nontraditional.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/misc/bool-bitwise-operation-nontraditional.cpp
@@ -15,10 +15,10 @@ bool& normal() {
bool bad() noexcept __attribute__((pure)) {
bool a = true, b = false;
a bitor b;
- // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
// CHECK-FIXES: a or b;
a bitand b;
- // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '&&' for boolean values instead of bitwise operator '&' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '&&' for boolean semantics instead of bitwise operator '&' [misc-bool-bitwise-operation]
// CHECK-FIXES: a and b;
a or_eq b;
// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '||' for boolean variable 'a' instead of bitwise operator '|=' [misc-bool-bitwise-operation]
@@ -31,10 +31,10 @@ bool bad() noexcept __attribute__((pure)) {
}
bool global_1 = bad() bitor bad();
-// CHECK-MESSAGES: :[[@LINE-1]]:23: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+// CHECK-MESSAGES: :[[@LINE-1]]:23: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
// CHECK-FIXES: bool global_1 = bad() or bad();
bool global_2 = bad() bitand bad();
-// CHECK-MESSAGES: :[[@LINE-1]]:23: warning: use logical operator '&&' for boolean values instead of bitwise operator '&' [misc-bool-bitwise-operation]
+// CHECK-MESSAGES: :[[@LINE-1]]:23: warning: use logical operator '&&' for boolean semantics instead of bitwise operator '&' [misc-bool-bitwise-operation]
// CHECK-FIXES: bool global_2 = bad() and bad();
using Boolean = bool;
@@ -42,10 +42,10 @@ using Boolean = bool;
bool bad_typedef() {
Boolean a = true, b = false;
a bitor b;
- // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
// CHECK-FIXES: a or b;
a bitand b;
- // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '&&' for boolean values instead of bitwise operator '&' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '&&' for boolean semantics instead of bitwise operator '&' [misc-bool-bitwise-operation]
// CHECK-FIXES: a and b;
a or_eq b;
// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '||' for boolean variable 'a' instead of bitwise operator '|=' [misc-bool-bitwise-operation]
@@ -62,19 +62,19 @@ void bad_side_effects() {
bool a = true, b = false;
a bitor function_with_possible_side_effects();
- // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
// CHECK-MESSAGES-NOT: :[[@LINE-2]]:{{.*}}: note: FIX-IT applied suggested code changes
a bitand function_with_possible_side_effects();
- // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '&&' for boolean values instead of bitwise operator '&' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '&&' for boolean semantics instead of bitwise operator '&' [misc-bool-bitwise-operation]
// CHECK-MESSAGES-NOT: :[[@LINE-2]]:{{.*}}: note: FIX-IT applied suggested code changes
function_with_possible_side_effects() bitor a;
- // CHECK-MESSAGES: :[[@LINE-1]]:43: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:43: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
// CHECK-FIXES: function_with_possible_side_effects() or a;
function_with_possible_side_effects() bitand a;
- // CHECK-MESSAGES: :[[@LINE-1]]:43: warning: use logical operator '&&' for boolean values instead of bitwise operator '&' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:43: warning: use logical operator '&&' for boolean semantics instead of bitwise operator '&' [misc-bool-bitwise-operation]
// CHECK-FIXES: function_with_possible_side_effects() and a;
a or_eq function_with_possible_side_effects();
// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '||' for boolean variable 'a' instead of bitwise operator '|=' [misc-bool-bitwise-operation]
@@ -88,19 +88,19 @@ void bad_side_effects() {
bool c = true;
a or function_with_possible_side_effects() bitor c;
- // CHECK-MESSAGES: :[[@LINE-1]]:48: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:48: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
// CHECK-FIXES: a or function_with_possible_side_effects() or c;
function_with_possible_side_effects() or b bitor c;
- // CHECK-MESSAGES: :[[@LINE-1]]:48: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:48: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
// CHECK-FIXES: function_with_possible_side_effects() or b or c;
a and function_with_possible_side_effects() bitand c;
- // CHECK-MESSAGES: :[[@LINE-1]]:49: warning: use logical operator '&&' for boolean values instead of bitwise operator '&' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:49: warning: use logical operator '&&' for boolean semantics instead of bitwise operator '&' [misc-bool-bitwise-operation]
// CHECK-FIXES: a and function_with_possible_side_effects() and c;
function_with_possible_side_effects() and b bitand c;
- // CHECK-MESSAGES: :[[@LINE-1]]:49: warning: use logical operator '&&' for boolean values instead of bitwise operator '&' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:49: warning: use logical operator '&&' for boolean semantics instead of bitwise operator '&' [misc-bool-bitwise-operation]
// CHECK-FIXES: function_with_possible_side_effects() and b and c;
// but here the count of evaluation migh be changed - no fix must be provided
@@ -128,10 +128,10 @@ void bad_side_effects_volatile() {
bool c = true;
a bitor b;
- // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
// CHECK-MESSAGES-NOT: :[[@LINE-2]]:{{.*}}: note: FIX-IT applied suggested code changes
a bitand b;
- // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '&&' for boolean values instead of bitwise operator '&' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '&&' for boolean semantics instead of bitwise operator '&' [misc-bool-bitwise-operation]
// CHECK-MESSAGES-NOT: :[[@LINE-2]]:{{.*}}: note: FIX-IT applied suggested code changes
a or_eq b;
@@ -142,38 +142,38 @@ void bad_side_effects_volatile() {
// CHECK-MESSAGES-NOT: :[[@LINE-2]]:{{.*}}: note: FIX-IT applied suggested code changes
(a bitor c) bitor b;
- // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
- // CHECK-MESSAGES: :[[@LINE-2]]:17: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-2]]:17: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
// CHECK-FIXES: (a or c) bitor b;
a bitor c bitor b;
- // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
- // CHECK-MESSAGES: :[[@LINE-2]]:15: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-2]]:15: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
// CHECK-FIXES: a or c bitor b;
}
void bad_with_priors() {
bool a = false, b = true, c = true;
a and b bitor c;
- // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
// CHECK-FIXES: a and (b or c);
a and b bitand c;
- // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use logical operator '&&' for boolean values instead of bitwise operator '&' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use logical operator '&&' for boolean semantics instead of bitwise operator '&' [misc-bool-bitwise-operation]
// CHECK-FIXES: a and b and c;
a or b bitand c;
- // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: use logical operator '&&' for boolean values instead of bitwise operator '&' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: use logical operator '&&' for boolean semantics instead of bitwise operator '&' [misc-bool-bitwise-operation]
// CHECK-FIXES: a or b and c;
a or b bitor c;
- // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
// CHECK-FIXES: a or b or c;
b bitor c and a;
- // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
// CHECK-FIXES: (b or c) and a;
bool q = (true and false bitor true) and (false bitor true and (false and true bitor false));
- // CHECK-MESSAGES: :[[@LINE-1]]:30: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
- // CHECK-MESSAGES: :[[@LINE-2]]:53: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
- // CHECK-MESSAGES: :[[@LINE-3]]:84: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:30: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-2]]:53: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-3]]:84: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
// CHECK-FIXES: bool q = (true and (false or true)) and ((false or true) and (false and (true or false)));
}
@@ -181,23 +181,23 @@ void bad_with_priors2() {
bool a = false, b = true, c = true;
bool r;
a xor b bitand c;
- // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use logical operator '&&' for boolean values instead of bitwise operator '&' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use logical operator '&&' for boolean semantics instead of bitwise operator '&' [misc-bool-bitwise-operation]
// CHECK-FIXES: a xor (b and c);
// braces added in the first change
a bitor b bitand c;
- // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
- // CHECK-MESSAGES: :[[@LINE-2]]:15: warning: use logical operator '&&' for boolean values instead of bitwise operator '&' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-2]]:15: warning: use logical operator '&&' for boolean semantics instead of bitwise operator '&' [misc-bool-bitwise-operation]
// CHECK-FIXES: a or (b and c);
b bitand c xor a;
- // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '&&' for boolean values instead of bitwise operator '&' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '&&' for boolean semantics instead of bitwise operator '&' [misc-bool-bitwise-operation]
// CHECK-FIXES: (b and c) xor a;
// braces added in the first change
b bitand c bitor a;
- // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '&&' for boolean values instead of bitwise operator '&' [misc-bool-bitwise-operation]
- // CHECK-MESSAGES: :[[@LINE-2]]:16: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '&&' for boolean semantics instead of bitwise operator '&' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-2]]:16: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
// CHECK-FIXES: (b and c) or a;
}
@@ -209,49 +209,49 @@ void bad_has_ancestor() {
bool a = false, b = true, c = true;
bool d = false;
d xor (a and b bitand c);
- // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: use logical operator '&&' for boolean values instead of bitwise operator '&' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: use logical operator '&&' for boolean semantics instead of bitwise operator '&' [misc-bool-bitwise-operation]
// CHECK-FIXES: d xor (a and b and c);
a xor ident(b bitand c or a);
- // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: use logical operator '&&' for boolean values instead of bitwise operator '&' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: use logical operator '&&' for boolean semantics instead of bitwise operator '&' [misc-bool-bitwise-operation]
// CHECK-FIXES: a xor ident(b and c or a);
a bitor ident(a ? b bitand c : c);
- // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: use logical operator '&&' for boolean values instead of bitwise operator '&' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: use logical operator '&&' for boolean semantics instead of bitwise operator '&' [misc-bool-bitwise-operation]
// CHECK-FIXES: a bitor ident(a ? b and c : c);
}
void bad_with_priors_already_braced() {
bool a = false, b = true, c = true;
a and (b bitor c);
- // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
// CHECK-FIXES: a and (b or c);
(b bitor c) and a;
- // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
// CHECK-FIXES: (b or c) and a;
bool q = (true and (false bitor true)) and ((false bitor true) and (false and (true bitor false)));
- // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
- // CHECK-MESSAGES: :[[@LINE-2]]:56: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
- // CHECK-MESSAGES: :[[@LINE-3]]:89: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-2]]:56: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-3]]:89: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
// CHECK-FIXES: bool q = (true and (false or true)) and ((false or true) and (false and (true or false)));
a xor (b bitand c);
- // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: use logical operator '&&' for boolean values instead of bitwise operator '&' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: use logical operator '&&' for boolean semantics instead of bitwise operator '&' [misc-bool-bitwise-operation]
// CHECK-FIXES: a xor (b and c);
a bitor (b bitand c);
- // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
- // CHECK-MESSAGES: :[[@LINE-2]]:16: warning: use logical operator '&&' for boolean values instead of bitwise operator '&' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-2]]:16: warning: use logical operator '&&' for boolean semantics instead of bitwise operator '&' [misc-bool-bitwise-operation]
// CHECK-FIXES: a or (b and c);
(b bitand c) xor a;
- // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: use logical operator '&&' for boolean values instead of bitwise operator '&' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: use logical operator '&&' for boolean semantics instead of bitwise operator '&' [misc-bool-bitwise-operation]
// CHECK-FIXES: (b and c) xor a;
(b bitand c) bitor a;
- // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: use logical operator '&&' for boolean values instead of bitwise operator '&' [misc-bool-bitwise-operation]
- // CHECK-MESSAGES: :[[@LINE-2]]:18: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: use logical operator '&&' for boolean semantics instead of bitwise operator '&' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-2]]:18: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
// CHECK-FIXES: (b and c) or a;
}
@@ -281,10 +281,10 @@ void bad_with_priors_compound_already_braced() {
void bad_no_fixit() {
bool b = false;
normal() or_eq b;
- // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: use logical operator '||' for boolean values instead of bitwise operator '|=' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|=' [misc-bool-bitwise-operation]
// CHECK-MESSAGES-NOT: :[[@LINE-2]]:{{.*}}: note: FIX-IT applied suggested code changes
normal() and_eq b;
- // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: use logical operator '&&' for boolean values instead of bitwise operator '&=' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: use logical operator '&&' for boolean semantics instead of bitwise operator '&=' [misc-bool-bitwise-operation]
// CHECK-MESSAGES-NOT: :[[@LINE-2]]:{{.*}}: note: FIX-IT applied suggested code changes
}
@@ -302,10 +302,10 @@ void bad_in_macro() {
// change operator - BAD
IDENT(a bitor) b;
- // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
// CHECK-MESSAGES-NOT: :[[@LINE-2]]:{{.*}}: note: FIX-IT applied suggested code changes
a IDENT(bitand b);
- // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use logical operator '&&' for boolean values instead of bitwise operator '&' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use logical operator '&&' for boolean semantics instead of bitwise operator '&' [misc-bool-bitwise-operation]
// CHECK-MESSAGES-NOT: :[[@LINE-2]]:{{.*}}: note: FIX-IT applied suggested code changes
IDENT(a or_eq) b;
// CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use logical operator '||' for boolean variable 'a' instead of bitwise operator '|=' [misc-bool-bitwise-operation]
@@ -316,34 +316,34 @@ void bad_in_macro() {
// change operator - GOOD
IDENT(a) bitor b;
- // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
// CHECK-FIXES: IDENT(a) or b;
a bitand IDENT(b);
- // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '&&' for boolean values instead of bitwise operator '&' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '&&' for boolean semantics instead of bitwise operator '&' [misc-bool-bitwise-operation]
// CHECK-FIXES: a and IDENT(b);
IDENT(a) bitand IDENT(b);
- // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: use logical operator '&&' for boolean values instead of bitwise operator '&' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: use logical operator '&&' for boolean semantics instead of bitwise operator '&' [misc-bool-bitwise-operation]
// CHECK-FIXES: IDENT(a) and IDENT(b);
// insert `)` - BAD
bool c = true, e = false;
a and b bitor IDENT(c and) e;
- // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
// CHECK-MESSAGES-NOT: :[[@LINE-2]]:{{.*}}: note: FIX-IT applied suggested code changes
// insert `)` - GOOD
a and b bitor c IDENT(and e);
- // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
// CHECK-FIXES: a and (b or c) IDENT(and e);
// insert `(` - BAD
a IDENT(and b) bitor c and e;
- // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
// CHECK-MESSAGES-NOT: :[[@LINE-2]]:{{.*}}: note: FIX-IT applied suggested code changes
// insert `(` - GOOD
IDENT(a and) b bitor c and e;
- // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
// CHECK-FIXES: IDENT(a and) (b or c) and e;
bool ab = false;
@@ -364,9 +364,9 @@ void bad_in_macro_fixit() {
// FIXME: implement fixit for all of these cases
a MY_OR b;
- // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
a MY_AND b;
- // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '&&' for boolean values instead of bitwise operator '&' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '&&' for boolean semantics instead of bitwise operator '&' [misc-bool-bitwise-operation]
a MY_OR_ASSIGN b;
// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '||' for boolean variable 'a' instead of bitwise operator '|=' [misc-bool-bitwise-operation]
a MY_AND_ASSIGN b;
diff --git a/clang-tools-extra/test/clang-tidy/checkers/misc/bool-bitwise-operation-not-only-bool-operand-compound.cpp b/clang-tools-extra/test/clang-tidy/checkers/misc/bool-bitwise-operation-not-only-bool-operand-compound.cpp
index ec9f536afe0a8..2369da53d26ef 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/misc/bool-bitwise-operation-not-only-bool-operand-compound.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/misc/bool-bitwise-operation-not-only-bool-operand-compound.cpp
@@ -15,6 +15,6 @@ void assign_to_boolean(unsigned flags, bool value) {
// CHECK-FIXES: value = value || flags << 1;
value |= (flags << 1) | (flags << 2);
// CHECK-MESSAGES: :[[@LINE-1]]:11: warning: use logical operator '||' for boolean variable 'value' instead of bitwise operator '|=' [misc-bool-bitwise-operation]
- // CHECK-MESSAGES: :[[@LINE-2]]:27: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-2]]:27: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
// CHECK-FIXES: value = value || (flags << 1) || (flags << 2);
}
diff --git a/clang-tools-extra/test/clang-tidy/checkers/misc/bool-bitwise-operation-not-only-bool-operand.cpp b/clang-tools-extra/test/clang-tidy/checkers/misc/bool-bitwise-operation-not-only-bool-operand.cpp
index 603d49c7b24e6..e0cd992fa78a4 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/misc/bool-bitwise-operation-not-only-bool-operand.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/misc/bool-bitwise-operation-not-only-bool-operand.cpp
@@ -12,239 +12,239 @@ void general(unsigned flags, bool value) {
void take(bool value) {}
template<bool bb = true | 1>
-// CHECK-MESSAGES: :[[@LINE-1]]:25: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+// CHECK-MESSAGES: :[[@LINE-1]]:25: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
// CHECK-FIXES: template<bool bb = true || 1>
void assign_to_boolean(unsigned flags, bool value) {
struct A { bool a = true | 1; };
- // CHECK-MESSAGES: :[[@LINE-1]]:30: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:30: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
// CHECK-FIXES: struct A { bool a = true || 1; };
struct B { union { bool a = true | 1; }; };
- // CHECK-MESSAGES: :[[@LINE-1]]:38: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:38: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
// CHECK-FIXES: struct B { union { bool a = true || 1; }; };
bool result = (flags << 1) | value;
- // CHECK-MESSAGES: :[[@LINE-1]]:32: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:32: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
// CHECK-FIXES: bool result = (flags << 1) || value;
bool a = (flags << 2) | value,
- // CHECK-MESSAGES: :[[@LINE-1]]:27: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:27: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
// CHECK-FIXES: bool a = (flags << 2) || value,
b = (flags << 4) | value,
- // CHECK-MESSAGES: :[[@LINE-1]]:27: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:27: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
// CHECK-FIXES: b = (flags << 4) || value,
c = (flags << 8) | value;
- // CHECK-MESSAGES: :[[@LINE-1]]:27: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:27: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
// CHECK-FIXES: c = (flags << 8) || value;
result = (flags << 1) | value;
- // CHECK-MESSAGES: :[[@LINE-1]]:27: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:27: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
// CHECK-FIXES: result = (flags << 1) || value;
take((flags << 1) | value);
- // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
// CHECK-FIXES: take((flags << 1) || value);
result = (flags << 1) | (flags << 2) | value;
- // CHECK-MESSAGES: :[[@LINE-1]]:27: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
- // CHECK-MESSAGES: :[[@LINE-2]]:42: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:27: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-2]]:42: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
// CHECK-FIXES: result = (flags << 1) || (flags << 2) || value;
result = (flags << 1) | (flags << 2) | (flags << 4) | value;
- // CHECK-MESSAGES: :[[@LINE-1]]:27: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
- // CHECK-MESSAGES: :[[@LINE-2]]:42: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
- // CHECK-MESSAGES: :[[@LINE-3]]:57: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:27: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-2]]:42: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-3]]:57: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
// CHECK-FIXES: result = (flags << 1) || (flags << 2) || (flags << 4) || value;
}
template<bool bb = (true | 1)>
-// CHECK-MESSAGES: :[[@LINE-1]]:26: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+// CHECK-MESSAGES: :[[@LINE-1]]:26: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
// CHECK-FIXES: template<bool bb = (true || 1)>
void assign_to_boolean_parens(unsigned flags, bool value) {
struct A { bool a = (true | 1); };
- // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
// CHECK-FIXES: struct A { bool a = (true || 1); };
struct B { union { bool a = (true | 1); }; };
- // CHECK-MESSAGES: :[[@LINE-1]]:39: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:39: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
// CHECK-FIXES: struct B { union { bool a = (true || 1); }; };
bool result = ((flags << 1) | value);
- // CHECK-MESSAGES: :[[@LINE-1]]:33: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:33: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
// CHECK-FIXES: bool result = ((flags << 1) || value);
bool a = ((flags << 2) | value),
- // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
// CHECK-FIXES: bool a = ((flags << 2) || value),
b = ((flags << 4) | value),
- // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
// CHECK-FIXES: b = ((flags << 4) || value),
c = ((flags << 8) | value);
- // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
// CHECK-FIXES: c = ((flags << 8) || value);
result = ((flags << 1) | value);
- // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
// CHECK-FIXES: result = ((flags << 1) || value);
take(((flags << 1) | value));
- // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
// CHECK-FIXES: take(((flags << 1) || value));
result = ((flags << 1) | (flags << 2) | value);
- // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
- // CHECK-MESSAGES: :[[@LINE-2]]:43: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-2]]:43: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
// CHECK-FIXES: result = ((flags << 1) || (flags << 2) || value);
result = ((flags << 1) | (flags << 2) | (flags << 4) | value);
- // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
- // CHECK-MESSAGES: :[[@LINE-2]]:43: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
- // CHECK-MESSAGES: :[[@LINE-3]]:58: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-2]]:43: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-3]]:58: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
// CHECK-FIXES: result = ((flags << 1) || (flags << 2) || (flags << 4) || value);
}
template<bool bb = ((true | 1))>
-// CHECK-MESSAGES: :[[@LINE-1]]:27: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+// CHECK-MESSAGES: :[[@LINE-1]]:27: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
// CHECK-FIXES: template<bool bb = ((true || 1))>
void assign_to_boolean_parens2(unsigned flags, bool value) {
struct A { bool a = ((true | 1)); };
- // CHECK-MESSAGES: :[[@LINE-1]]:32: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:32: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
// CHECK-FIXES: struct A { bool a = ((true || 1)); };
struct B { union { bool a = ((true | 1)); }; };
- // CHECK-MESSAGES: :[[@LINE-1]]:40: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:40: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
// CHECK-FIXES: struct B { union { bool a = ((true || 1)); }; };
bool result = (((flags << 1) | value));
- // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
// CHECK-FIXES: bool result = (((flags << 1) || value));
bool a = (((flags << 2) | value)),
- // CHECK-MESSAGES: :[[@LINE-1]]:29: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:29: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
// CHECK-FIXES: bool a = (((flags << 2) || value)),
b = (((flags << 4) | value)),
- // CHECK-MESSAGES: :[[@LINE-1]]:29: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:29: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
// CHECK-FIXES: b = (((flags << 4) || value)),
c = (((flags << 8) | value));
- // CHECK-MESSAGES: :[[@LINE-1]]:29: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:29: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
// CHECK-FIXES: c = (((flags << 8) || value));
result = (((flags << 1) | value));
- // CHECK-MESSAGES: :[[@LINE-1]]:29: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:29: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
// CHECK-FIXES: result = (((flags << 1) || value));
take((((flags << 1) | value)));
- // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
// CHECK-FIXES: take((((flags << 1) || value)));
result = (((flags << 1) | (flags << 2) | value));
- // CHECK-MESSAGES: :[[@LINE-1]]:29: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
- // CHECK-MESSAGES: :[[@LINE-2]]:44: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:29: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-2]]:44: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
// CHECK-FIXES: result = (((flags << 1) || (flags << 2) || value));
result = (((flags << 1) | (flags << 2) | (flags << 4) | value));
- // CHECK-MESSAGES: :[[@LINE-1]]:29: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
- // CHECK-MESSAGES: :[[@LINE-2]]:44: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
- // CHECK-MESSAGES: :[[@LINE-3]]:59: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:29: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-2]]:44: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-3]]:59: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
// CHECK-FIXES: result = (((flags << 1) || (flags << 2) || (flags << 4) || value));
}
// functional cast
template<bool bb = bool(true | 1)>
-// CHECK-MESSAGES: :[[@LINE-1]]:30: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+// CHECK-MESSAGES: :[[@LINE-1]]:30: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
// CHECK-FIXES: template<bool bb = bool(true || 1)>
void assign_to_boolean_fcast(unsigned flags, bool value) {
struct A { bool a = bool(true | 1); };
- // CHECK-MESSAGES: :[[@LINE-1]]:35: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:35: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
// CHECK-FIXES: struct A { bool a = bool(true || 1); };
struct B { union { bool a = bool(true | 1); }; };
- // CHECK-MESSAGES: :[[@LINE-1]]:43: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:43: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
// CHECK-FIXES: struct B { union { bool a = bool(true || 1); }; };
bool result = bool((flags << 1) | value);
- // CHECK-MESSAGES: :[[@LINE-1]]:37: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:37: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
// CHECK-FIXES: bool result = bool((flags << 1) || value);
bool a = bool((flags << 2) | value),
- // CHECK-MESSAGES: :[[@LINE-1]]:32: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:32: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
// CHECK-FIXES: bool a = bool((flags << 2) || value),
b = bool((flags << 4) | value),
- // CHECK-MESSAGES: :[[@LINE-1]]:32: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:32: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
// CHECK-FIXES: b = bool((flags << 4) || value),
c = bool((flags << 8) | value);
- // CHECK-MESSAGES: :[[@LINE-1]]:32: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:32: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
// CHECK-FIXES: c = bool((flags << 8) || value);
result = bool((flags << 1) | value);
- // CHECK-MESSAGES: :[[@LINE-1]]:32: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:32: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
// CHECK-FIXES: result = bool((flags << 1) || value);
take(bool((flags << 1) | value));
- // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
// CHECK-FIXES: take(bool((flags << 1) || value));
result = bool((flags << 1) | (flags << 2) | value);
- // CHECK-MESSAGES: :[[@LINE-1]]:32: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
- // CHECK-MESSAGES: :[[@LINE-2]]:47: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:32: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-2]]:47: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
// CHECK-FIXES: result = bool((flags << 1) || (flags << 2) || value);
result = bool((flags << 1) | (flags << 2) | (flags << 4) | value);
- // CHECK-MESSAGES: :[[@LINE-1]]:32: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
- // CHECK-MESSAGES: :[[@LINE-2]]:47: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
- // CHECK-MESSAGES: :[[@LINE-3]]:62: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:32: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-2]]:47: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-3]]:62: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
// CHECK-FIXES: result = bool((flags << 1) || (flags << 2) || (flags << 4) || value);
}
// C-style cast
template<bool bb = (bool)(true | 1)>
-// CHECK-MESSAGES: :[[@LINE-1]]:32: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+// CHECK-MESSAGES: :[[@LINE-1]]:32: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
// CHECK-FIXES: template<bool bb = (bool)(true || 1)>
void assign_to_boolean_ccast(unsigned flags, bool value) {
struct A { bool a = (bool)(true | 1); };
- // CHECK-MESSAGES: :[[@LINE-1]]:37: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:37: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
// CHECK-FIXES: struct A { bool a = (bool)(true || 1); };
struct B { union { bool a = (bool)(true | 1); }; };
- // CHECK-MESSAGES: :[[@LINE-1]]:45: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:45: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
// CHECK-FIXES: struct B { union { bool a = (bool)(true || 1); }; };
bool result = (bool)((flags << 1) | value);
- // CHECK-MESSAGES: :[[@LINE-1]]:39: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:39: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
// CHECK-FIXES: bool result = (bool)((flags << 1) || value);
bool a = (bool)((flags << 2) | value),
- // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
// CHECK-FIXES: bool a = (bool)((flags << 2) || value),
b = (bool)((flags << 4) | value),
- // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
// CHECK-FIXES: b = (bool)((flags << 4) || value),
c = (bool)((flags << 8) | value);
- // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
// CHECK-FIXES: c = (bool)((flags << 8) || value);
result = (bool)((flags << 1) | value);
- // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
// CHECK-FIXES: result = (bool)((flags << 1) || value);
take(bool((flags << 1) | value));
- // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
// CHECK-FIXES: take(bool((flags << 1) || value));
result = (bool)((flags << 1) | (flags << 2) | value);
- // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
- // CHECK-MESSAGES: :[[@LINE-2]]:49: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-2]]:49: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
// CHECK-FIXES: result = (bool)((flags << 1) || (flags << 2) || value);
result = (bool)((flags << 1) | (flags << 2) | (flags << 4) | value);
- // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
- // CHECK-MESSAGES: :[[@LINE-2]]:49: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
- // CHECK-MESSAGES: :[[@LINE-3]]:64: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-2]]:49: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-3]]:64: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
// CHECK-FIXES: result = (bool)((flags << 1) || (flags << 2) || (flags << 4) || value);
}
// static_cast
template<bool bb = static_cast<bool>(true | 1)>
-// CHECK-MESSAGES: :[[@LINE-1]]:43: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+// CHECK-MESSAGES: :[[@LINE-1]]:43: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
// CHECK-FIXES: template<bool bb = static_cast<bool>(true || 1)>
void assign_to_boolean_scast(unsigned flags, bool value) {
struct A { bool a = static_cast<bool>(true | 1); };
- // CHECK-MESSAGES: :[[@LINE-1]]:48: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:48: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
// CHECK-FIXES: struct A { bool a = static_cast<bool>(true || 1); };
struct B { union { bool a = static_cast<bool>(true | 1); }; };
- // CHECK-MESSAGES: :[[@LINE-1]]:56: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:56: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
// CHECK-FIXES: struct B { union { bool a = static_cast<bool>(true || 1); }; };
bool result = static_cast<bool>((flags << 1) | value);
- // CHECK-MESSAGES: :[[@LINE-1]]:50: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:50: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
// CHECK-FIXES: bool result = static_cast<bool>((flags << 1) || value);
bool a = static_cast<bool>((flags << 2) | value),
- // CHECK-MESSAGES: :[[@LINE-1]]:45: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:45: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
// CHECK-FIXES: bool a = static_cast<bool>((flags << 2) || value),
b = static_cast<bool>((flags << 4) | value),
- // CHECK-MESSAGES: :[[@LINE-1]]:45: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:45: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
// CHECK-FIXES: b = static_cast<bool>((flags << 4) || value),
c = static_cast<bool>((flags << 8) | value);
- // CHECK-MESSAGES: :[[@LINE-1]]:45: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:45: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
// CHECK-FIXES: c = static_cast<bool>((flags << 8) || value);
result = static_cast<bool>((flags << 1) | value);
- // CHECK-MESSAGES: :[[@LINE-1]]:45: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:45: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
// CHECK-FIXES: result = static_cast<bool>((flags << 1) || value);
take(static_cast<bool>((flags << 1) | value));
- // CHECK-MESSAGES: :[[@LINE-1]]:41: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:41: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
// CHECK-FIXES: take(static_cast<bool>((flags << 1) || value));
result = static_cast<bool>((flags << 1) | (flags << 2) | value);
- // CHECK-MESSAGES: :[[@LINE-1]]:45: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
- // CHECK-MESSAGES: :[[@LINE-2]]:60: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:45: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-2]]:60: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
// CHECK-FIXES: result = static_cast<bool>((flags << 1) || (flags << 2) || value);
result = static_cast<bool>((flags << 1) | (flags << 2) | (flags << 4) | value);
- // CHECK-MESSAGES: :[[@LINE-1]]:45: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
- // CHECK-MESSAGES: :[[@LINE-2]]:60: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
- // CHECK-MESSAGES: :[[@LINE-3]]:75: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:45: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-2]]:60: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-3]]:75: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
// CHECK-FIXES: result = static_cast<bool>((flags << 1) || (flags << 2) || (flags << 4) || value);
}
diff --git a/clang-tools-extra/test/clang-tidy/checkers/misc/bool-bitwise-operation.c b/clang-tools-extra/test/clang-tidy/checkers/misc/bool-bitwise-operation.c
index 777189f12bbd3..04c831ab63dd0 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/misc/bool-bitwise-operation.c
+++ b/clang-tools-extra/test/clang-tidy/checkers/misc/bool-bitwise-operation.c
@@ -12,10 +12,10 @@ void normal() {
void bad() {
_Bool a = 1, b = 0;
a | b;
- // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-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 '&' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '&&' for boolean semantics instead of bitwise operator '&' [misc-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 '|=' [misc-bool-bitwise-operation]
diff --git a/clang-tools-extra/test/clang-tidy/checkers/misc/bool-bitwise-operation.cpp b/clang-tools-extra/test/clang-tidy/checkers/misc/bool-bitwise-operation.cpp
index 2cc725cb8781f..5c2eb5d065514 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/misc/bool-bitwise-operation.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/misc/bool-bitwise-operation.cpp
@@ -15,10 +15,10 @@ bool& normal() {
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 '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-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 '&' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '&&' for boolean semantics instead of bitwise operator '&' [misc-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 '|=' [misc-bool-bitwise-operation]
@@ -31,10 +31,10 @@ bool bad() noexcept __attribute__((pure)) {
}
bool global_1 = bad() | bad();
-// CHECK-MESSAGES: :[[@LINE-1]]:23: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+// CHECK-MESSAGES: :[[@LINE-1]]:23: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-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 '&' [misc-bool-bitwise-operation]
+// CHECK-MESSAGES: :[[@LINE-1]]:23: warning: use logical operator '&&' for boolean semantics instead of bitwise operator '&' [misc-bool-bitwise-operation]
// CHECK-FIXES: bool global_2 = bad() && bad();
using Boolean = bool;
@@ -42,10 +42,10 @@ 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 '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-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 '&' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '&&' for boolean semantics instead of bitwise operator '&' [misc-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 '|=' [misc-bool-bitwise-operation]
@@ -62,19 +62,19 @@ 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 '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-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 '&' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '&&' for boolean semantics instead of bitwise operator '&' [misc-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 '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:43: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-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 '&' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:43: warning: use logical operator '&&' for boolean semantics instead of bitwise operator '&' [misc-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 '|=' [misc-bool-bitwise-operation]
@@ -88,19 +88,19 @@ void bad_side_effects() {
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 '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:48: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-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 '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:48: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-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 '&' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:48: warning: use logical operator '&&' for boolean semantics instead of bitwise operator '&' [misc-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 '&' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:48: warning: use logical operator '&&' for boolean semantics instead of bitwise operator '&' [misc-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
@@ -128,10 +128,10 @@ void bad_side_effects_volatile() {
bool c = true;
a | b;
- // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-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 '&' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '&&' for boolean semantics instead of bitwise operator '&' [misc-bool-bitwise-operation]
// CHECK-MESSAGES-NOT: :[[@LINE-2]]:{{.*}}: note: FIX-IT applied suggested code changes
a |= b;
@@ -142,60 +142,60 @@ void bad_side_effects_volatile() {
// CHECK-MESSAGES-NOT: :[[@LINE-2]]:{{.*}}: note: FIX-IT applied suggested code changes
(a | c) | b;
- // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
- // CHECK-MESSAGES: :[[@LINE-2]]:13: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-2]]:13: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
// CHECK-FIXES: (a || c) | b;
a | c | b;
- // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
- // CHECK-MESSAGES: :[[@LINE-2]]:11: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-2]]:11: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
// CHECK-FIXES: a || c | b;
}
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 '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-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 '&' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: use logical operator '&&' for boolean semantics instead of bitwise operator '&' [misc-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 '&' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: use logical operator '&&' for boolean semantics instead of bitwise operator '&' [misc-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 '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-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 '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-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 '|' [misc-bool-bitwise-operation]
- // CHECK-MESSAGES: :[[@LINE-2]]:47: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
- // CHECK-MESSAGES: :[[@LINE-3]]:72: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:29: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-2]]:47: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-3]]:72: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-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 '&' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: use logical operator '&&' for boolean semantics instead of bitwise operator '&' [misc-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 '|' [misc-bool-bitwise-operation]
- // CHECK-MESSAGES: :[[@LINE-2]]:11: warning: use logical operator '&&' for boolean values instead of bitwise operator '&' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-2]]:11: warning: use logical operator '&&' for boolean semantics instead of bitwise operator '&' [misc-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 '&' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '&&' for boolean semantics instead of bitwise operator '&' [misc-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 '&' [misc-bool-bitwise-operation]
- // CHECK-MESSAGES: :[[@LINE-2]]:11: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '&&' for boolean semantics instead of bitwise operator '&' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-2]]:11: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
// CHECK-FIXES: (b && c) || a;
}
@@ -207,49 +207,49 @@ 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 '&' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: use logical operator '&&' for boolean semantics instead of bitwise operator '&' [misc-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 '&' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: use logical operator '&&' for boolean semantics instead of bitwise operator '&' [misc-bool-bitwise-operation]
// CHECK-FIXES: a ^ ident(b && c || a);
a | ident(a ? b & c : c);
- // CHECK-MESSAGES: :[[@LINE-1]]:21: warning: use logical operator '&&' for boolean values instead of bitwise operator '&' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:21: warning: use logical operator '&&' for boolean semantics instead of bitwise operator '&' [misc-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 '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-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 '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-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 '|' [misc-bool-bitwise-operation]
- // CHECK-MESSAGES: :[[@LINE-2]]:50: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
- // CHECK-MESSAGES: :[[@LINE-3]]:77: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:30: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-2]]:50: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-3]]:77: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-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 '&' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: use logical operator '&&' for boolean semantics instead of bitwise operator '&' [misc-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 '|' [misc-bool-bitwise-operation]
- // CHECK-MESSAGES: :[[@LINE-2]]:12: warning: use logical operator '&&' for boolean values instead of bitwise operator '&' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-2]]:12: warning: use logical operator '&&' for boolean semantics instead of bitwise operator '&' [misc-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 '&' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: use logical operator '&&' for boolean semantics instead of bitwise operator '&' [misc-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 '&' [misc-bool-bitwise-operation]
- // CHECK-MESSAGES: :[[@LINE-2]]:13: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: use logical operator '&&' for boolean semantics instead of bitwise operator '&' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-2]]:13: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
// CHECK-FIXES: (b && c) || a;
}
@@ -279,10 +279,10 @@ void bad_with_priors_compound_already_braced() {
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 '|=' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|=' [misc-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 '&=' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: use logical operator '&&' for boolean semantics instead of bitwise operator '&=' [misc-bool-bitwise-operation]
// CHECK-MESSAGES-NOT: :[[@LINE-2]]:{{.*}}: note: FIX-IT applied suggested code changes
}
@@ -300,10 +300,10 @@ void bad_in_macro() {
// change operator - BAD
IDENT(a |) b;
- // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
// CHECK-MESSAGES-NOT: :[[@LINE-2]]:{{.*}}: note: FIX-IT applied suggested code changes
a IDENT(& b);
- // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use logical operator '&&' for boolean values instead of bitwise operator '&' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use logical operator '&&' for boolean semantics instead of bitwise operator '&' [misc-bool-bitwise-operation]
// CHECK-MESSAGES-NOT: :[[@LINE-2]]:{{.*}}: note: FIX-IT applied suggested code changes
IDENT(a |=) b;
// CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use logical operator '||' for boolean variable 'a' instead of bitwise operator '|=' [misc-bool-bitwise-operation]
@@ -314,34 +314,34 @@ void bad_in_macro() {
// change operator - GOOD
IDENT(a) | b;
- // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
// CHECK-FIXES: IDENT(a) || b;
a & IDENT(b);
- // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '&&' for boolean values instead of bitwise operator '&' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '&&' for boolean semantics instead of bitwise operator '&' [misc-bool-bitwise-operation]
// CHECK-FIXES: a && IDENT(b);
IDENT(a) & IDENT(b);
- // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: use logical operator '&&' for boolean values instead of bitwise operator '&' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: use logical operator '&&' for boolean semantics instead of bitwise operator '&' [misc-bool-bitwise-operation]
// CHECK-FIXES: IDENT(a) && IDENT(b);
// insert `)` - BAD
bool c = true, e = false;
a && b | IDENT(c &&) e;
- // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
// CHECK-MESSAGES-NOT: :[[@LINE-2]]:{{.*}}: note: FIX-IT applied suggested code changes
// insert `)` - GOOD
a && b | c IDENT(&& e);
- // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
// CHECK-FIXES: a && (b || c) IDENT(&& e);
// insert `(` - BAD
a IDENT(&& b) | c && e;
- // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
// CHECK-MESSAGES-NOT: :[[@LINE-2]]:{{.*}}: note: FIX-IT applied suggested code changes
// insert `(` - GOOD
IDENT(a &&) b | c && e;
- // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
// CHECK-FIXES: IDENT(a &&) (b || c) && e;
bool ab = false;
@@ -362,9 +362,9 @@ void bad_in_macro_fixit() {
// FIXME: implement fixit for all of these cases
a MY_OR b;
- // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '||' for boolean values instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
a MY_AND b;
- // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '&&' for boolean values instead of bitwise operator '&' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '&&' for boolean semantics instead of bitwise operator '&' [misc-bool-bitwise-operation]
a MY_OR_ASSIGN b;
// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '||' for boolean variable 'a' instead of bitwise operator '|=' [misc-bool-bitwise-operation]
a MY_AND_ASSIGN b;
>From dfa7ce4d2b8a1f44188836b8c312ba4f0a68f234 Mon Sep 17 00:00:00 2001
From: Denis Mikhailov <denismikhaylov38 at gmail.com>
Date: Sat, 8 Nov 2025 21:37:57 +0300
Subject: [PATCH 11/28] Implement handling of members
---
.../misc/BoolBitwiseOperationCheck.cpp | 38 +++--
.../bool-bitwise-operation-static-members.cpp | 35 +++++
.../bool-bitwise-operation-struct-members.cpp | 143 ++++++++++++++++++
3 files changed, 204 insertions(+), 12 deletions(-)
create mode 100644 clang-tools-extra/test/clang-tidy/checkers/misc/bool-bitwise-operation-static-members.cpp
create mode 100644 clang-tools-extra/test/clang-tidy/checkers/misc/bool-bitwise-operation-struct-members.cpp
diff --git a/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.cpp b/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.cpp
index a37935ea3a0d0..65e936e054b72 100644
--- a/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.cpp
+++ b/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.cpp
@@ -58,9 +58,10 @@ static bool assignsToBoolean(const BinaryOperator *BinOp, ASTContext *AC) {
static const NamedDecl *
getLHSNamedDeclIfCompoundAssign(const BinaryOperator *BO) {
if (BO->isCompoundAssignmentOp()) {
- const auto *DeclRefLHS =
- dyn_cast<DeclRefExpr>(BO->getLHS()->IgnoreImpCasts());
- return DeclRefLHS ? DeclRefLHS->getDecl() : nullptr;
+ if (const auto *DeclRefLHS = dyn_cast<DeclRefExpr>(BO->getLHS()->IgnoreImpCasts()))
+ return DeclRefLHS->getDecl();
+ else if (const auto *MemberLHS = dyn_cast<MemberExpr>(BO->getLHS()->IgnoreImpCasts()))
+ return MemberLHS->getMemberDecl();
}
return nullptr;
}
@@ -132,6 +133,17 @@ static bool isBooleanBitwise(const BinaryOperator *BinOp, ASTContext *AC,
return false;
}
+static const Expr* getValidCompoundsLHS(const BinaryOperator* BinOp) {
+ assert(BinOp->isCompoundAssignmentOp());
+
+ if (const auto *DeclRefLHS = dyn_cast<DeclRefExpr>(BinOp->getLHS()->IgnoreImpCasts()))
+ return DeclRefLHS;
+ else if (const auto *MemberLHS = dyn_cast<MemberExpr>(BinOp->getLHS()->IgnoreImpCasts()))
+ return MemberLHS;
+
+ return nullptr;
+}
+
BoolBitwiseOperationCheck::BoolBitwiseOperationCheck(StringRef Name,
ClangTidyContext *Context)
: ClangTidyCheck(Name, Context),
@@ -159,9 +171,8 @@ void BoolBitwiseOperationCheck::emitWarningAndChangeOperatorsIfPossible(
auto DiagEmitter = [BinOp, this] {
const NamedDecl *ND = getLHSNamedDeclIfCompoundAssign(BinOp);
return diag(BinOp->getOperatorLoc(),
- "use logical operator '%0' for boolean %select{variable "
- "%2|semantics}1 instead of bitwise operator '%3'")
- << translate(BinOp->getOpcodeStr()) << (ND == nullptr) << ND
+ "use logical operator '%0' for boolean %select{%select{member|variable}2 %3|semantics}1 instead of bitwise operator '%4'")
+ << translate(BinOp->getOpcodeStr()) << (ND == nullptr) << (!isa<MemberExpr>(BinOp->getLHS()->IgnoreImpCasts())) << ND
<< BinOp->getOpcodeStr();
};
@@ -201,19 +212,22 @@ void BoolBitwiseOperationCheck::emitWarningAndChangeOperatorsIfPossible(
FixItHint InsertEqual;
if (BinOp->isCompoundAssignmentOp()) {
- const auto *DeclRefLHS =
- dyn_cast<DeclRefExpr>(BinOp->getLHS()->IgnoreImpCasts());
- if (!DeclRefLHS)
+ const auto *LHS = getValidCompoundsLHS(BinOp);
+ if (!LHS)
return static_cast<void>(DiagEmitter());
- const SourceLocation LocLHS = DeclRefLHS->getEndLoc();
+ const SourceLocation LocLHS = LHS->getEndLoc();
if (LocLHS.isInvalid() || LocLHS.isMacroID())
return static_cast<void>(IgnoreMacros || DiagEmitter());
const SourceLocation InsertLoc =
clang::Lexer::getLocForEndOfToken(LocLHS, 0, SM, Ctx.getLangOpts());
if (InsertLoc.isInvalid() || InsertLoc.isMacroID())
return static_cast<void>(IgnoreMacros || DiagEmitter());
- InsertEqual = FixItHint::CreateInsertion(
- InsertLoc, " = " + DeclRefLHS->getDecl()->getNameAsString());
+ auto SourceText = static_cast<std::string>(Lexer::getSourceText(
+ CharSourceRange::getTokenRange(LHS->getSourceRange()),
+ SM, Ctx.getLangOpts()
+ ));
+ llvm::erase_if(SourceText, [](unsigned char ch) { return std::isspace(ch); });
+ InsertEqual = FixItHint::CreateInsertion(InsertLoc, " = " + SourceText);
}
auto ReplaceOperator = FixItHint::CreateReplacement(TokenRange, FixSpelling);
diff --git a/clang-tools-extra/test/clang-tidy/checkers/misc/bool-bitwise-operation-static-members.cpp b/clang-tools-extra/test/clang-tidy/checkers/misc/bool-bitwise-operation-static-members.cpp
new file mode 100644
index 0000000000000..1ba4108c4c9c6
--- /dev/null
+++ b/clang-tools-extra/test/clang-tidy/checkers/misc/bool-bitwise-operation-static-members.cpp
@@ -0,0 +1,35 @@
+// RUN: %check_clang_tidy %s misc-bool-bitwise-operation %t
+
+struct A {
+ static int first;
+ static bool second;
+};
+
+int A::first = 100;
+bool A::second = false;
+
+void normal() {
+ int b = 200;
+
+ A::first | b;
+ A::first & b;
+ A::first |= b;
+ A::first &= b;
+}
+
+void bad() {
+ bool b = false;
+
+ A::second | b;
+ // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-FIXES: A::second || b;
+ A::second & b;
+ // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: use logical operator '&&' for boolean semantics instead of bitwise operator '&' [misc-bool-bitwise-operation]
+ // CHECK-FIXES: A::second && b;
+ A::second |= b;
+ // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: use logical operator '||' for boolean variable 'second' instead of bitwise operator '|=' [misc-bool-bitwise-operation]
+ // CHECK-FIXES: A::second = A::second || b;
+ A::second &= b;
+ // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: use logical operator '&&' for boolean variable 'second' instead of bitwise operator '&=' [misc-bool-bitwise-operation]
+ // CHECK-FIXES: A::second = A::second && b;
+}
diff --git a/clang-tools-extra/test/clang-tidy/checkers/misc/bool-bitwise-operation-struct-members.cpp b/clang-tools-extra/test/clang-tidy/checkers/misc/bool-bitwise-operation-struct-members.cpp
new file mode 100644
index 0000000000000..cc0fee5fd54a7
--- /dev/null
+++ b/clang-tools-extra/test/clang-tidy/checkers/misc/bool-bitwise-operation-struct-members.cpp
@@ -0,0 +1,143 @@
+// RUN: %check_clang_tidy %s misc-bool-bitwise-operation %t
+
+struct A {
+ int first;
+ bool second;
+};
+
+void normal() {
+ A a {100, false};
+ int b = 200;
+
+ a.first | b;
+ a.first & b;
+ a.first |= b;
+ a.first &= b;
+}
+
+void bad() {
+ A a {-1, true};
+ bool b = false;
+
+ a.second | b;
+ // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-FIXES: a.second || b;
+ a.second & b;
+ // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: use logical operator '&&' for boolean semantics instead of bitwise operator '&' [misc-bool-bitwise-operation]
+ // CHECK-FIXES: a.second && b;
+ a.second |= b;
+ // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: use logical operator '||' for boolean member 'second' instead of bitwise operator '|=' [misc-bool-bitwise-operation]
+ // CHECK-FIXES: a.second = a.second || b;
+ a.second &= b;
+ // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: use logical operator '&&' for boolean member 'second' instead of bitwise operator '&=' [misc-bool-bitwise-operation]
+ // CHECK-FIXES: a.second = a.second && b;
+}
+
+void bad_two_lines() {
+ A a {-1, true};
+ bool b = false;
+
+ a.
+ second | b;
+ // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-FIXES: second || b;
+ a.
+ second & b;
+ // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: use logical operator '&&' for boolean semantics instead of bitwise operator '&' [misc-bool-bitwise-operation]
+ // CHECK-FIXES: second && b;
+ a.
+ second |= b;
+ // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use logical operator '||' for boolean member 'second' instead of bitwise operator '|=' [misc-bool-bitwise-operation]
+ // CHECK-FIXES: second = a.second || b;
+ a
+ .
+ second &= b;
+ // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: use logical operator '&&' for boolean member 'second' instead of bitwise operator '&=' [misc-bool-bitwise-operation]
+ // CHECK-FIXES: second = a.second && b;
+ a
+ .second &= b;
+ // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use logical operator '&&' for boolean member 'second' instead of bitwise operator '&=' [misc-bool-bitwise-operation]
+ // CHECK-FIXES: .second = a.second && b;
+}
+
+void bad_side_effects_volatile() {
+ volatile A a {-1, true};
+ bool b = false;
+
+ a.second | b;
+ // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES-NOT: :[[@LINE-2]]:{{.*}}: note: FIX-IT applied suggested code changes
+ a.second & b;
+ // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: use logical operator '&&' for boolean semantics instead of bitwise operator '&' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES-NOT: :[[@LINE-2]]:{{.*}}: note: FIX-IT applied suggested code changes
+ a.second |= b;
+ // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: use logical operator '||' for boolean member 'second' instead of bitwise operator '|=' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES-NOT: :[[@LINE-2]]:{{.*}}: note: FIX-IT applied suggested code changes
+ a.second &= b;
+ // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: use logical operator '&&' for boolean member 'second' instead of bitwise operator '&=' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES-NOT: :[[@LINE-2]]:{{.*}}: note: FIX-IT applied suggested code changes
+}
+
+struct VolatileA {
+ volatile bool second;
+};
+
+void bad_side_effects_volatile2() {
+ VolatileA a {true};
+ bool b = false;
+
+ a.second | b;
+ // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES-NOT: :[[@LINE-2]]:{{.*}}: note: FIX-IT applied suggested code changes
+ a.second & b;
+ // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: use logical operator '&&' for boolean semantics instead of bitwise operator '&' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES-NOT: :[[@LINE-2]]:{{.*}}: note: FIX-IT applied suggested code changes
+ a.second |= b;
+ // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: use logical operator '||' for boolean member 'second' instead of bitwise operator '|=' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES-NOT: :[[@LINE-2]]:{{.*}}: note: FIX-IT applied suggested code changes
+ a.second &= b;
+ // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: use logical operator '&&' for boolean member 'second' instead of bitwise operator '&=' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES-NOT: :[[@LINE-2]]:{{.*}}: note: FIX-IT applied suggested code changes
+}
+
+void bad_arrow() {
+ A a {-1, true};
+ auto* pa = &a;
+ bool b = false;
+
+ pa->second | b;
+ // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
+ // CHECK-FIXES: pa->second || b;
+ pa->second & b;
+ // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: use logical operator '&&' for boolean semantics instead of bitwise operator '&' [misc-bool-bitwise-operation]
+ // CHECK-FIXES: pa->second && b;
+ pa->second |= b;
+ // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: use logical operator '||' for boolean member 'second' instead of bitwise operator '|=' [misc-bool-bitwise-operation]
+ // CHECK-FIXES: pa->second = pa->second || b;
+ pa->second &= b;
+ // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: use logical operator '&&' for boolean member 'second' instead of bitwise operator '&=' [misc-bool-bitwise-operation]
+ // CHECK-FIXES: pa->second = pa->second && b;
+}
+
+struct B {
+ bool& access();
+};
+
+void bad_no_fixit() {
+ B b;
+ bool c = false;
+ b.access() |= c;
+ // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|=' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES-NOT: :[[@LINE-2]]:{{.*}}: note: FIX-IT applied suggested code changes
+ b.access() &= c;
+ // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: use logical operator '&&' for boolean semantics instead of bitwise operator '&=' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES-NOT: :[[@LINE-2]]:{{.*}}: note: FIX-IT applied suggested code changes
+
+ auto* pb = &b;
+ pb->access() |= c;
+ // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|=' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES-NOT: :[[@LINE-2]]:{{.*}}: note: FIX-IT applied suggested code changes
+ pb->access() &= c;
+ // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: use logical operator '&&' for boolean semantics instead of bitwise operator '&=' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES-NOT: :[[@LINE-2]]:{{.*}}: note: FIX-IT applied suggested code changes
+}
>From cb9d520d86d8c707c87e308c2fcc7b65aebe408b Mon Sep 17 00:00:00 2001
From: Denis Mikhailov <denismikhaylov38 at gmail.com>
Date: Sat, 8 Nov 2025 21:46:08 +0300
Subject: [PATCH 12/28] Simplify the warning message
---
.../misc/BoolBitwiseOperationCheck.cpp | 16 +------
.../checks/misc/bool-bitwise-operation.rst | 6 +--
...-operation-change-possible-side-effect.cpp | 24 +++++-----
.../bool-bitwise-operation-ignore-macros.cpp | 2 +-
.../bool-bitwise-operation-nontraditional.cpp | 48 +++++++++----------
...eration-not-only-bool-operand-compound.cpp | 4 +-
.../bool-bitwise-operation-static-members.cpp | 4 +-
.../bool-bitwise-operation-struct-members.cpp | 22 ++++-----
.../checkers/misc/bool-bitwise-operation.c | 4 +-
.../checkers/misc/bool-bitwise-operation.cpp | 48 +++++++++----------
10 files changed, 83 insertions(+), 95 deletions(-)
diff --git a/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.cpp b/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.cpp
index 65e936e054b72..402f6baac5e57 100644
--- a/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.cpp
+++ b/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.cpp
@@ -55,17 +55,6 @@ static bool assignsToBoolean(const BinaryOperator *BinOp, ASTContext *AC) {
return false;
}
-static const NamedDecl *
-getLHSNamedDeclIfCompoundAssign(const BinaryOperator *BO) {
- if (BO->isCompoundAssignmentOp()) {
- if (const auto *DeclRefLHS = dyn_cast<DeclRefExpr>(BO->getLHS()->IgnoreImpCasts()))
- return DeclRefLHS->getDecl();
- else if (const auto *MemberLHS = dyn_cast<MemberExpr>(BO->getLHS()->IgnoreImpCasts()))
- return MemberLHS->getMemberDecl();
- }
- return nullptr;
-}
-
constexpr std::array<std::pair<llvm::StringRef, llvm::StringRef>, 8U>
OperatorsTransformation{{{"|", "||"},
{"|=", "||"},
@@ -169,10 +158,9 @@ void BoolBitwiseOperationCheck::emitWarningAndChangeOperatorsIfPossible(
const BinaryOperator *BinOp, const BinaryOperator *ParentBinOp,
const clang::SourceManager &SM, clang::ASTContext &Ctx) {
auto DiagEmitter = [BinOp, this] {
- const NamedDecl *ND = getLHSNamedDeclIfCompoundAssign(BinOp);
return diag(BinOp->getOperatorLoc(),
- "use logical operator '%0' for boolean %select{%select{member|variable}2 %3|semantics}1 instead of bitwise operator '%4'")
- << translate(BinOp->getOpcodeStr()) << (ND == nullptr) << (!isa<MemberExpr>(BinOp->getLHS()->IgnoreImpCasts())) << ND
+ "use logical operator '%0' for boolean semantics instead of bitwise operator '%1'")
+ << translate(BinOp->getOpcodeStr())
<< BinOp->getOpcodeStr();
};
diff --git a/clang-tools-extra/docs/clang-tidy/checks/misc/bool-bitwise-operation.rst b/clang-tools-extra/docs/clang-tidy/checks/misc/bool-bitwise-operation.rst
index 3682a74a5119d..e70ac82779644 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/misc/bool-bitwise-operation.rst
+++ b/clang-tools-extra/docs/clang-tidy/checks/misc/bool-bitwise-operation.rst
@@ -13,9 +13,9 @@ to implicit integer conversions and missed short-circuit evaluation.
.. code-block:: c++
bool invalid = false;
- invalid |= x > limit.x; // warning: use logical operator '||' for boolean variable 'invalid' instead of bitwise operator '|='
- invalid |= y > limit.y; // warning: use logical operator '||' for boolean variable 'invalid' instead of bitwise operator '|='
- invalid |= z > limit.z; // warning: use logical operator '||' for boolean variable 'invalid' instead of bitwise operator '|='
+ invalid |= x > limit.x; // warning: use logical operator '||' for boolean semantics instead of bitwise operator '|='
+ invalid |= y > limit.y; // warning: use logical operator '||' for boolean semantics instead of bitwise operator '|='
+ invalid |= z > limit.z; // warning: use logical operator '||' for boolean semantics instead of bitwise operator '|='
if (invalid) {
// error handling
}
diff --git a/clang-tools-extra/test/clang-tidy/checkers/misc/bool-bitwise-operation-change-possible-side-effect.cpp b/clang-tools-extra/test/clang-tidy/checkers/misc/bool-bitwise-operation-change-possible-side-effect.cpp
index d58f3ecd836fd..a51220be391bc 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/misc/bool-bitwise-operation-change-possible-side-effect.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/misc/bool-bitwise-operation-change-possible-side-effect.cpp
@@ -16,29 +16,29 @@ void bad_possible_side_effects() {
// CHECK-FIXES: a && function_with_possible_side_effects();
a |= function_with_possible_side_effects();
- // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '||' for boolean variable 'a' instead of bitwise operator '|=' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|=' [misc-bool-bitwise-operation]
// CHECK-FIXES: a = a || function_with_possible_side_effects();
a &= function_with_possible_side_effects();
- // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '&&' for boolean variable 'a' instead of bitwise operator '&=' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '&&' for boolean semantics instead of bitwise operator '&=' [misc-bool-bitwise-operation]
// CHECK-FIXES: a = a && function_with_possible_side_effects();
bool c = true;
a &= function_with_possible_side_effects() && c;
- // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '&&' for boolean variable 'a' instead of bitwise operator '&=' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '&&' for boolean semantics instead of bitwise operator '&=' [misc-bool-bitwise-operation]
// CHECK-FIXES: a = a && function_with_possible_side_effects() && c;
a &= b && function_with_possible_side_effects();
- // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '&&' for boolean variable 'a' instead of bitwise operator '&=' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '&&' for boolean semantics instead of bitwise operator '&=' [misc-bool-bitwise-operation]
// CHECK-FIXES: a = a && b && function_with_possible_side_effects();
a |= function_with_possible_side_effects() || c;
- // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '||' for boolean variable 'a' instead of bitwise operator '|=' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|=' [misc-bool-bitwise-operation]
// CHECK-FIXES: a = a || function_with_possible_side_effects() || c;
a |= b || function_with_possible_side_effects();
- // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '||' for boolean variable 'a' instead of bitwise operator '|=' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|=' [misc-bool-bitwise-operation]
// CHECK-FIXES: a = a || b || function_with_possible_side_effects();
}
@@ -55,28 +55,28 @@ void bad_definitely_side_effects() {
// CHECK-MESSAGES-NOT: :[[@LINE-2]]:{{.*}}: note: FIX-IT applied suggested code changes
a |= (acc++, b);
- // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '||' for boolean variable 'a' instead of bitwise operator '|=' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|=' [misc-bool-bitwise-operation]
// CHECK-MESSAGES-NOT: :[[@LINE-2]]:{{.*}}: note: FIX-IT applied suggested code changes
a &= (acc++, b);
- // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '&&' for boolean variable 'a' instead of bitwise operator '&=' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '&&' for boolean semantics instead of bitwise operator '&=' [misc-bool-bitwise-operation]
// CHECK-MESSAGES-NOT: :[[@LINE-2]]:{{.*}}: note: FIX-IT applied suggested code changes
bool c = true;
a &= (acc++, b) && c;
- // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '&&' for boolean variable 'a' instead of bitwise operator '&=' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '&&' for boolean semantics instead of bitwise operator '&=' [misc-bool-bitwise-operation]
// CHECK-MESSAGES-NOT: :[[@LINE-2]]:{{.*}}: note: FIX-IT applied suggested code changes
a &= b && (acc++, c);
- // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '&&' for boolean variable 'a' instead of bitwise operator '&=' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '&&' for boolean semantics instead of bitwise operator '&=' [misc-bool-bitwise-operation]
// CHECK-MESSAGES-NOT: :[[@LINE-2]]:{{.*}}: note: FIX-IT applied suggested code changes
a |= (acc++, b) || c;
- // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '||' for boolean variable 'a' instead of bitwise operator '|=' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|=' [misc-bool-bitwise-operation]
// CHECK-MESSAGES-NOT: :[[@LINE-2]]:{{.*}}: note: FIX-IT applied suggested code changes
a |= b || (acc++, c);
- // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '||' for boolean variable 'a' instead of bitwise operator '|=' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|=' [misc-bool-bitwise-operation]
// CHECK-MESSAGES-NOT: :[[@LINE-2]]:{{.*}}: note: FIX-IT applied suggested code changes
}
\ No newline at end of file
diff --git a/clang-tools-extra/test/clang-tidy/checkers/misc/bool-bitwise-operation-ignore-macros.cpp b/clang-tools-extra/test/clang-tidy/checkers/misc/bool-bitwise-operation-ignore-macros.cpp
index 43faddcc3beea..d2b742cf207d1 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/misc/bool-bitwise-operation-ignore-macros.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/misc/bool-bitwise-operation-ignore-macros.cpp
@@ -48,6 +48,6 @@ void bad_in_macro() {
// insert ` = a`- GOOD
b &= CAT(a, b);
- // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '&&' for boolean variable 'b' instead of bitwise operator '&=' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '&&' for boolean semantics instead of bitwise operator '&=' [misc-bool-bitwise-operation]
// CHECK-FIXES: b = b && CAT(a, b);
}
\ No newline at end of file
diff --git a/clang-tools-extra/test/clang-tidy/checkers/misc/bool-bitwise-operation-nontraditional.cpp b/clang-tools-extra/test/clang-tidy/checkers/misc/bool-bitwise-operation-nontraditional.cpp
index 314f2087dcf3a..974ebe1f75053 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/misc/bool-bitwise-operation-nontraditional.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/misc/bool-bitwise-operation-nontraditional.cpp
@@ -21,10 +21,10 @@ bool bad() noexcept __attribute__((pure)) {
// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '&&' for boolean semantics instead of bitwise operator '&' [misc-bool-bitwise-operation]
// CHECK-FIXES: a and b;
a or_eq b;
- // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '||' for boolean variable 'a' instead of bitwise operator '|=' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|=' [misc-bool-bitwise-operation]
// CHECK-FIXES: a = a or b;
a and_eq b;
- // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '&&' for boolean variable 'a' instead of bitwise operator '&=' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '&&' for boolean semantics instead of bitwise operator '&=' [misc-bool-bitwise-operation]
// CHECK-FIXES: a = a and b;
return true;
@@ -48,10 +48,10 @@ bool bad_typedef() {
// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '&&' for boolean semantics instead of bitwise operator '&' [misc-bool-bitwise-operation]
// CHECK-FIXES: a and b;
a or_eq b;
- // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '||' for boolean variable 'a' instead of bitwise operator '|=' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|=' [misc-bool-bitwise-operation]
// CHECK-FIXES: a = a or b;
a and_eq b;
- // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '&&' for boolean variable 'a' instead of bitwise operator '&=' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '&&' for boolean semantics instead of bitwise operator '&=' [misc-bool-bitwise-operation]
// CHECK-FIXES: a = a and b;
return true;
}
@@ -77,11 +77,11 @@ void bad_side_effects() {
// CHECK-MESSAGES: :[[@LINE-1]]:43: warning: use logical operator '&&' for boolean semantics instead of bitwise operator '&' [misc-bool-bitwise-operation]
// CHECK-FIXES: function_with_possible_side_effects() and a;
a or_eq function_with_possible_side_effects();
- // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '||' for boolean variable 'a' instead of bitwise operator '|=' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|=' [misc-bool-bitwise-operation]
// CHECK-MESSAGES-NOT: :[[@LINE-2]]:{{.*}}: note: FIX-IT applied suggested code changes
a and_eq function_with_possible_side_effects();
- // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '&&' for boolean variable 'a' instead of bitwise operator '&=' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '&&' for boolean semantics instead of bitwise operator '&=' [misc-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
@@ -106,19 +106,19 @@ void bad_side_effects() {
// but here the count of evaluation migh be changed - no fix must be provided
a and_eq function_with_possible_side_effects() and c;
- // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '&&' for boolean variable 'a' instead of bitwise operator '&=' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '&&' for boolean semantics instead of bitwise operator '&=' [misc-bool-bitwise-operation]
// CHECK-MESSAGES-NOT: :[[@LINE-2]]:{{.*}}: note: FIX-IT applied suggested code changes
a and_eq b and function_with_possible_side_effects();
- // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '&&' for boolean variable 'a' instead of bitwise operator '&=' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '&&' for boolean semantics instead of bitwise operator '&=' [misc-bool-bitwise-operation]
// CHECK-MESSAGES-NOT: :[[@LINE-2]]:{{.*}}: note: FIX-IT applied suggested code changes
a or_eq function_with_possible_side_effects() or c;
- // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '||' for boolean variable 'a' instead of bitwise operator '|=' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|=' [misc-bool-bitwise-operation]
// CHECK-MESSAGES-NOT: :[[@LINE-2]]:{{.*}}: note: FIX-IT applied suggested code changes
a or_eq b or function_with_possible_side_effects();
- // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '||' for boolean variable 'a' instead of bitwise operator '|=' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|=' [misc-bool-bitwise-operation]
// CHECK-MESSAGES-NOT: :[[@LINE-2]]:{{.*}}: note: FIX-IT applied suggested code changes
}
@@ -135,10 +135,10 @@ void bad_side_effects_volatile() {
// CHECK-MESSAGES-NOT: :[[@LINE-2]]:{{.*}}: note: FIX-IT applied suggested code changes
a or_eq b;
- // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '||' for boolean variable 'a' instead of bitwise operator '|=' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|=' [misc-bool-bitwise-operation]
// CHECK-MESSAGES-NOT: :[[@LINE-2]]:{{.*}}: note: FIX-IT applied suggested code changes
a and_eq b;
- // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '&&' for boolean variable 'a' instead of bitwise operator '&=' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '&&' for boolean semantics instead of bitwise operator '&=' [misc-bool-bitwise-operation]
// CHECK-MESSAGES-NOT: :[[@LINE-2]]:{{.*}}: note: FIX-IT applied suggested code changes
(a bitor c) bitor b;
@@ -258,23 +258,23 @@ void bad_with_priors_already_braced() {
void bad_with_priors_compound() {
bool a = false, b = true, c = true;
a and_eq b or c;
- // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '&&' for boolean variable 'a' instead of bitwise operator '&=' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '&&' for boolean semantics instead of bitwise operator '&=' [misc-bool-bitwise-operation]
// CHECK-FIXES: a = a and (b or c);
a or_eq b or c;
- // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '||' for boolean variable 'a' instead of bitwise operator '|=' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|=' [misc-bool-bitwise-operation]
// CHECK-FIXES: a = a or b or c;
a and_eq b and c;
- // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '&&' for boolean variable 'a' instead of bitwise operator '&=' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '&&' for boolean semantics instead of bitwise operator '&=' [misc-bool-bitwise-operation]
// CHECK-FIXES: a = a and b and c;
a or_eq b and c;
- // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '||' for boolean variable 'a' instead of bitwise operator '|=' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|=' [misc-bool-bitwise-operation]
// CHECK-FIXES: a = a or b and c;
}
void bad_with_priors_compound_already_braced() {
bool a = false, b = true, c = true;
a and_eq (b or c);
- // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '&&' for boolean variable 'a' instead of bitwise operator '&=' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '&&' for boolean semantics instead of bitwise operator '&=' [misc-bool-bitwise-operation]
// CHECK-FIXES: a = a and (b or c);
}
@@ -308,10 +308,10 @@ void bad_in_macro() {
// CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use logical operator '&&' for boolean semantics instead of bitwise operator '&' [misc-bool-bitwise-operation]
// CHECK-MESSAGES-NOT: :[[@LINE-2]]:{{.*}}: note: FIX-IT applied suggested code changes
IDENT(a or_eq) b;
- // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use logical operator '||' for boolean variable 'a' instead of bitwise operator '|=' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|=' [misc-bool-bitwise-operation]
// CHECK-MESSAGES-NOT: :[[@LINE-2]]:{{.*}}: note: FIX-IT applied suggested code changes
a IDENT(and_eq b);
- // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use logical operator '&&' for boolean variable 'a' instead of bitwise operator '&=' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use logical operator '&&' for boolean semantics instead of bitwise operator '&=' [misc-bool-bitwise-operation]
// CHECK-MESSAGES-NOT: :[[@LINE-2]]:{{.*}}: note: FIX-IT applied suggested code changes
// change operator - GOOD
@@ -349,12 +349,12 @@ void bad_in_macro() {
bool ab = false;
// insert ` = a` - BAD
CAT(a, b) and_eq b;
- // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: use logical operator '&&' for boolean variable 'ab' instead of bitwise operator '&=' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: use logical operator '&&' for boolean semantics instead of bitwise operator '&=' [misc-bool-bitwise-operation]
// CHECK-MESSAGES-NOT: :[[@LINE-2]]:{{.*}}: note: FIX-IT applied suggested code changes
// insert ` = a`- GOOD
b and_eq CAT(a, b);
- // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '&&' for boolean variable 'b' instead of bitwise operator '&=' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '&&' for boolean semantics instead of bitwise operator '&=' [misc-bool-bitwise-operation]
// CHECK-FIXES: b = b and CAT(a, b);
}
@@ -368,11 +368,11 @@ void bad_in_macro_fixit() {
a MY_AND b;
// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '&&' for boolean semantics instead of bitwise operator '&' [misc-bool-bitwise-operation]
a MY_OR_ASSIGN b;
- // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '||' for boolean variable 'a' instead of bitwise operator '|=' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|=' [misc-bool-bitwise-operation]
a MY_AND_ASSIGN b;
- // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '&&' for boolean variable 'a' instead of bitwise operator '&=' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '&&' for boolean semantics instead of bitwise operator '&=' [misc-bool-bitwise-operation]
IDENT(a and_eq b);
- // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use logical operator '&&' for boolean variable 'a' instead of bitwise operator '&=' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use logical operator '&&' for boolean semantics instead of bitwise operator '&=' [misc-bool-bitwise-operation]
}
template<typename T>
diff --git a/clang-tools-extra/test/clang-tidy/checkers/misc/bool-bitwise-operation-not-only-bool-operand-compound.cpp b/clang-tools-extra/test/clang-tidy/checkers/misc/bool-bitwise-operation-not-only-bool-operand-compound.cpp
index 2369da53d26ef..19d39bfad6fe6 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/misc/bool-bitwise-operation-not-only-bool-operand-compound.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/misc/bool-bitwise-operation-not-only-bool-operand-compound.cpp
@@ -11,10 +11,10 @@ void general(unsigned flags, bool value) {
void assign_to_boolean(unsigned flags, bool value) {
value |= flags << 1;
- // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: use logical operator '||' for boolean variable 'value' instead of bitwise operator '|=' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|=' [misc-bool-bitwise-operation]
// CHECK-FIXES: value = value || flags << 1;
value |= (flags << 1) | (flags << 2);
- // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: use logical operator '||' for boolean variable 'value' instead of bitwise operator '|=' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|=' [misc-bool-bitwise-operation]
// CHECK-MESSAGES: :[[@LINE-2]]:27: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
// CHECK-FIXES: value = value || (flags << 1) || (flags << 2);
}
diff --git a/clang-tools-extra/test/clang-tidy/checkers/misc/bool-bitwise-operation-static-members.cpp b/clang-tools-extra/test/clang-tidy/checkers/misc/bool-bitwise-operation-static-members.cpp
index 1ba4108c4c9c6..90ede4115a43f 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/misc/bool-bitwise-operation-static-members.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/misc/bool-bitwise-operation-static-members.cpp
@@ -27,9 +27,9 @@ void bad() {
// CHECK-MESSAGES: :[[@LINE-1]]:15: warning: use logical operator '&&' for boolean semantics instead of bitwise operator '&' [misc-bool-bitwise-operation]
// CHECK-FIXES: A::second && b;
A::second |= b;
- // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: use logical operator '||' for boolean variable 'second' instead of bitwise operator '|=' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|=' [misc-bool-bitwise-operation]
// CHECK-FIXES: A::second = A::second || b;
A::second &= b;
- // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: use logical operator '&&' for boolean variable 'second' instead of bitwise operator '&=' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: use logical operator '&&' for boolean semantics instead of bitwise operator '&=' [misc-bool-bitwise-operation]
// CHECK-FIXES: A::second = A::second && b;
}
diff --git a/clang-tools-extra/test/clang-tidy/checkers/misc/bool-bitwise-operation-struct-members.cpp b/clang-tools-extra/test/clang-tidy/checkers/misc/bool-bitwise-operation-struct-members.cpp
index cc0fee5fd54a7..464a0723d52f0 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/misc/bool-bitwise-operation-struct-members.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/misc/bool-bitwise-operation-struct-members.cpp
@@ -26,10 +26,10 @@ void bad() {
// CHECK-MESSAGES: :[[@LINE-1]]:14: warning: use logical operator '&&' for boolean semantics instead of bitwise operator '&' [misc-bool-bitwise-operation]
// CHECK-FIXES: a.second && b;
a.second |= b;
- // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: use logical operator '||' for boolean member 'second' instead of bitwise operator '|=' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|=' [misc-bool-bitwise-operation]
// CHECK-FIXES: a.second = a.second || b;
a.second &= b;
- // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: use logical operator '&&' for boolean member 'second' instead of bitwise operator '&=' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: use logical operator '&&' for boolean semantics instead of bitwise operator '&=' [misc-bool-bitwise-operation]
// CHECK-FIXES: a.second = a.second && b;
}
@@ -47,16 +47,16 @@ void bad_two_lines() {
// CHECK-FIXES: second && b;
a.
second |= b;
- // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use logical operator '||' for boolean member 'second' instead of bitwise operator '|=' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|=' [misc-bool-bitwise-operation]
// CHECK-FIXES: second = a.second || b;
a
.
second &= b;
- // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: use logical operator '&&' for boolean member 'second' instead of bitwise operator '&=' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: use logical operator '&&' for boolean semantics instead of bitwise operator '&=' [misc-bool-bitwise-operation]
// CHECK-FIXES: second = a.second && b;
a
.second &= b;
- // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use logical operator '&&' for boolean member 'second' instead of bitwise operator '&=' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use logical operator '&&' for boolean semantics instead of bitwise operator '&=' [misc-bool-bitwise-operation]
// CHECK-FIXES: .second = a.second && b;
}
@@ -71,10 +71,10 @@ void bad_side_effects_volatile() {
// CHECK-MESSAGES: :[[@LINE-1]]:14: warning: use logical operator '&&' for boolean semantics instead of bitwise operator '&' [misc-bool-bitwise-operation]
// CHECK-MESSAGES-NOT: :[[@LINE-2]]:{{.*}}: note: FIX-IT applied suggested code changes
a.second |= b;
- // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: use logical operator '||' for boolean member 'second' instead of bitwise operator '|=' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|=' [misc-bool-bitwise-operation]
// CHECK-MESSAGES-NOT: :[[@LINE-2]]:{{.*}}: note: FIX-IT applied suggested code changes
a.second &= b;
- // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: use logical operator '&&' for boolean member 'second' instead of bitwise operator '&=' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: use logical operator '&&' for boolean semantics instead of bitwise operator '&=' [misc-bool-bitwise-operation]
// CHECK-MESSAGES-NOT: :[[@LINE-2]]:{{.*}}: note: FIX-IT applied suggested code changes
}
@@ -93,10 +93,10 @@ void bad_side_effects_volatile2() {
// CHECK-MESSAGES: :[[@LINE-1]]:14: warning: use logical operator '&&' for boolean semantics instead of bitwise operator '&' [misc-bool-bitwise-operation]
// CHECK-MESSAGES-NOT: :[[@LINE-2]]:{{.*}}: note: FIX-IT applied suggested code changes
a.second |= b;
- // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: use logical operator '||' for boolean member 'second' instead of bitwise operator '|=' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|=' [misc-bool-bitwise-operation]
// CHECK-MESSAGES-NOT: :[[@LINE-2]]:{{.*}}: note: FIX-IT applied suggested code changes
a.second &= b;
- // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: use logical operator '&&' for boolean member 'second' instead of bitwise operator '&=' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: use logical operator '&&' for boolean semantics instead of bitwise operator '&=' [misc-bool-bitwise-operation]
// CHECK-MESSAGES-NOT: :[[@LINE-2]]:{{.*}}: note: FIX-IT applied suggested code changes
}
@@ -112,10 +112,10 @@ void bad_arrow() {
// CHECK-MESSAGES: :[[@LINE-1]]:16: warning: use logical operator '&&' for boolean semantics instead of bitwise operator '&' [misc-bool-bitwise-operation]
// CHECK-FIXES: pa->second && b;
pa->second |= b;
- // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: use logical operator '||' for boolean member 'second' instead of bitwise operator '|=' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|=' [misc-bool-bitwise-operation]
// CHECK-FIXES: pa->second = pa->second || b;
pa->second &= b;
- // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: use logical operator '&&' for boolean member 'second' instead of bitwise operator '&=' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: use logical operator '&&' for boolean semantics instead of bitwise operator '&=' [misc-bool-bitwise-operation]
// CHECK-FIXES: pa->second = pa->second && b;
}
diff --git a/clang-tools-extra/test/clang-tidy/checkers/misc/bool-bitwise-operation.c b/clang-tools-extra/test/clang-tidy/checkers/misc/bool-bitwise-operation.c
index 04c831ab63dd0..0df4b9c4ed680 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/misc/bool-bitwise-operation.c
+++ b/clang-tools-extra/test/clang-tidy/checkers/misc/bool-bitwise-operation.c
@@ -18,9 +18,9 @@ void bad() {
// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '&&' for boolean semantics instead of bitwise operator '&' [misc-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 '|=' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|=' [misc-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 '&=' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '&&' for boolean semantics instead of bitwise operator '&=' [misc-bool-bitwise-operation]
// CHECK-FIXES: a = a && b;
}
\ No newline at end of file
diff --git a/clang-tools-extra/test/clang-tidy/checkers/misc/bool-bitwise-operation.cpp b/clang-tools-extra/test/clang-tidy/checkers/misc/bool-bitwise-operation.cpp
index 5c2eb5d065514..07bc14c204004 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/misc/bool-bitwise-operation.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/misc/bool-bitwise-operation.cpp
@@ -21,10 +21,10 @@ bool bad() noexcept __attribute__((pure)) {
// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '&&' for boolean semantics instead of bitwise operator '&' [misc-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 '|=' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|=' [misc-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 '&=' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '&&' for boolean semantics instead of bitwise operator '&=' [misc-bool-bitwise-operation]
// CHECK-FIXES: a = a && b;
return true;
@@ -48,10 +48,10 @@ bool bad_typedef() {
// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '&&' for boolean semantics instead of bitwise operator '&' [misc-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 '|=' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|=' [misc-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 '&=' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '&&' for boolean semantics instead of bitwise operator '&=' [misc-bool-bitwise-operation]
// CHECK-FIXES: a = a && b;
return true;
}
@@ -77,11 +77,11 @@ void bad_side_effects() {
// CHECK-MESSAGES: :[[@LINE-1]]:43: warning: use logical operator '&&' for boolean semantics instead of bitwise operator '&' [misc-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 '|=' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|=' [misc-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 '&=' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '&&' for boolean semantics instead of bitwise operator '&=' [misc-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
@@ -106,19 +106,19 @@ void bad_side_effects() {
// 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 '&=' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '&&' for boolean semantics instead of bitwise operator '&=' [misc-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 '&=' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '&&' for boolean semantics instead of bitwise operator '&=' [misc-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 '|=' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|=' [misc-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 '|=' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|=' [misc-bool-bitwise-operation]
// CHECK-MESSAGES-NOT: :[[@LINE-2]]:{{.*}}: note: FIX-IT applied suggested code changes
}
@@ -135,10 +135,10 @@ void bad_side_effects_volatile() {
// 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 '|=' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|=' [misc-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 '&=' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '&&' for boolean semantics instead of bitwise operator '&=' [misc-bool-bitwise-operation]
// CHECK-MESSAGES-NOT: :[[@LINE-2]]:{{.*}}: note: FIX-IT applied suggested code changes
(a | c) | b;
@@ -256,23 +256,23 @@ void bad_with_priors_already_braced() {
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 '&=' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '&&' for boolean semantics instead of bitwise operator '&=' [misc-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 '|=' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|=' [misc-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 '&=' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '&&' for boolean semantics instead of bitwise operator '&=' [misc-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 '|=' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|=' [misc-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 '&=' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '&&' for boolean semantics instead of bitwise operator '&=' [misc-bool-bitwise-operation]
// CHECK-FIXES: a = a && (b || c);
}
@@ -306,10 +306,10 @@ void bad_in_macro() {
// CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use logical operator '&&' for boolean semantics instead of bitwise operator '&' [misc-bool-bitwise-operation]
// CHECK-MESSAGES-NOT: :[[@LINE-2]]:{{.*}}: note: FIX-IT applied suggested code changes
IDENT(a |=) b;
- // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use logical operator '||' for boolean variable 'a' instead of bitwise operator '|=' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|=' [misc-bool-bitwise-operation]
// CHECK-MESSAGES-NOT: :[[@LINE-2]]:{{.*}}: note: FIX-IT applied suggested code changes
a IDENT(&= b);
- // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use logical operator '&&' for boolean variable 'a' instead of bitwise operator '&=' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use logical operator '&&' for boolean semantics instead of bitwise operator '&=' [misc-bool-bitwise-operation]
// CHECK-MESSAGES-NOT: :[[@LINE-2]]:{{.*}}: note: FIX-IT applied suggested code changes
// change operator - GOOD
@@ -347,12 +347,12 @@ void bad_in_macro() {
bool ab = false;
// insert ` = a` - BAD
CAT(a, b) &= b;
- // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: use logical operator '&&' for boolean variable 'ab' instead of bitwise operator '&=' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: use logical operator '&&' for boolean semantics instead of bitwise operator '&=' [misc-bool-bitwise-operation]
// CHECK-MESSAGES-NOT: :[[@LINE-2]]:{{.*}}: note: FIX-IT applied suggested code changes
// insert ` = a`- GOOD
b &= CAT(a, b);
- // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '&&' for boolean variable 'b' instead of bitwise operator '&=' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '&&' for boolean semantics instead of bitwise operator '&=' [misc-bool-bitwise-operation]
// CHECK-FIXES: b = b && CAT(a, b);
}
@@ -366,11 +366,11 @@ void bad_in_macro_fixit() {
a MY_AND b;
// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '&&' for boolean semantics instead of bitwise operator '&' [misc-bool-bitwise-operation]
a MY_OR_ASSIGN b;
- // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '||' for boolean variable 'a' instead of bitwise operator '|=' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|=' [misc-bool-bitwise-operation]
a MY_AND_ASSIGN b;
- // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '&&' for boolean variable 'a' instead of bitwise operator '&=' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '&&' for boolean semantics instead of bitwise operator '&=' [misc-bool-bitwise-operation]
IDENT(a &= b);
- // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use logical operator '&&' for boolean variable 'a' instead of bitwise operator '&=' [misc-bool-bitwise-operation]
+ // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use logical operator '&&' for boolean semantics instead of bitwise operator '&=' [misc-bool-bitwise-operation]
}
template<typename T>
>From 6457ade991c847945d0f711e00eb7382450be070 Mon Sep 17 00:00:00 2001
From: Denis Mikhailov <denismikhaylov38 at gmail.com>
Date: Sat, 8 Nov 2025 21:50:54 +0300
Subject: [PATCH 13/28] format
---
.../misc/BoolBitwiseOperationCheck.cpp | 78 ++++++++++---------
.../misc/BoolBitwiseOperationCheck.h | 2 +-
2 files changed, 41 insertions(+), 39 deletions(-)
diff --git a/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.cpp b/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.cpp
index 402f6baac5e57..748bf889a19e2 100644
--- a/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.cpp
+++ b/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.cpp
@@ -75,44 +75,44 @@ static llvm::StringRef translate(llvm::StringRef Value) {
}
static bool isBooleanBitwise(const BinaryOperator *BinOp, ASTContext *AC,
- std::optional<bool> &rootAssignsToBoolean) {
+ std::optional<bool> &RootAssignsToBoolean) {
if (!BinOp)
return false;
for (const auto &[Bitwise, _] : OperatorsTransformation) {
if (BinOp->getOpcodeStr() == Bitwise) {
- bool lhsBoolean = BinOp->getLHS()
- ->IgnoreImpCasts()
- ->getType()
- .getDesugaredType(*AC)
- ->isBooleanType();
- bool rhsBoolean = BinOp->getRHS()
- ->IgnoreImpCasts()
- ->getType()
- .getDesugaredType(*AC)
- ->isBooleanType();
+ bool IsBooleanLHS = BinOp->getLHS()
+ ->IgnoreImpCasts()
+ ->getType()
+ .getDesugaredType(*AC)
+ ->isBooleanType();
+ bool IsBooleanRHS = BinOp->getRHS()
+ ->IgnoreImpCasts()
+ ->getType()
+ .getDesugaredType(*AC)
+ ->isBooleanType();
for (int i = 0; i < 2; ++i) {
- if (lhsBoolean && rhsBoolean) {
- rootAssignsToBoolean = rootAssignsToBoolean.value_or(false);
+ if (IsBooleanLHS && IsBooleanRHS) {
+ RootAssignsToBoolean = RootAssignsToBoolean.value_or(false);
return true;
}
if (assignsToBoolean(BinOp, AC) ||
- rootAssignsToBoolean.value_or(false)) {
- rootAssignsToBoolean = rootAssignsToBoolean.value_or(true);
+ RootAssignsToBoolean.value_or(false)) {
+ RootAssignsToBoolean = RootAssignsToBoolean.value_or(true);
return true;
}
- if (BinOp->isCompoundAssignmentOp() && lhsBoolean) {
- rootAssignsToBoolean = rootAssignsToBoolean.value_or(true);
+ if (BinOp->isCompoundAssignmentOp() && IsBooleanLHS) {
+ RootAssignsToBoolean = RootAssignsToBoolean.value_or(true);
return true;
}
std::optional<bool> DummyFlag = false;
- lhsBoolean =
- lhsBoolean ||
+ IsBooleanLHS =
+ IsBooleanLHS ||
isBooleanBitwise(dyn_cast<BinaryOperator>(
BinOp->getLHS()->IgnoreParenImpCasts()),
AC, DummyFlag);
- rhsBoolean =
- rhsBoolean ||
+ IsBooleanRHS =
+ IsBooleanRHS ||
isBooleanBitwise(dyn_cast<BinaryOperator>(
BinOp->getRHS()->IgnoreParenImpCasts()),
AC, DummyFlag);
@@ -122,12 +122,14 @@ static bool isBooleanBitwise(const BinaryOperator *BinOp, ASTContext *AC,
return false;
}
-static const Expr* getValidCompoundsLHS(const BinaryOperator* BinOp) {
+static const Expr *getValidCompoundsLHS(const BinaryOperator *BinOp) {
assert(BinOp->isCompoundAssignmentOp());
-
- if (const auto *DeclRefLHS = dyn_cast<DeclRefExpr>(BinOp->getLHS()->IgnoreImpCasts()))
+
+ if (const auto *DeclRefLHS =
+ dyn_cast<DeclRefExpr>(BinOp->getLHS()->IgnoreImpCasts()))
return DeclRefLHS;
- else if (const auto *MemberLHS = dyn_cast<MemberExpr>(BinOp->getLHS()->IgnoreImpCasts()))
+ else if (const auto *MemberLHS =
+ dyn_cast<MemberExpr>(BinOp->getLHS()->IgnoreImpCasts()))
return MemberLHS;
return nullptr;
@@ -159,9 +161,9 @@ void BoolBitwiseOperationCheck::emitWarningAndChangeOperatorsIfPossible(
const clang::SourceManager &SM, clang::ASTContext &Ctx) {
auto DiagEmitter = [BinOp, this] {
return diag(BinOp->getOperatorLoc(),
- "use logical operator '%0' for boolean semantics instead of bitwise operator '%1'")
- << translate(BinOp->getOpcodeStr())
- << BinOp->getOpcodeStr();
+ "use logical operator '%0' for boolean semantics instead of "
+ "bitwise operator '%1'")
+ << translate(BinOp->getOpcodeStr()) << BinOp->getOpcodeStr();
};
const bool HasVolatileOperand = llvm::any_of(
@@ -211,10 +213,10 @@ void BoolBitwiseOperationCheck::emitWarningAndChangeOperatorsIfPossible(
if (InsertLoc.isInvalid() || InsertLoc.isMacroID())
return static_cast<void>(IgnoreMacros || DiagEmitter());
auto SourceText = static_cast<std::string>(Lexer::getSourceText(
- CharSourceRange::getTokenRange(LHS->getSourceRange()),
- SM, Ctx.getLangOpts()
- ));
- llvm::erase_if(SourceText, [](unsigned char ch) { return std::isspace(ch); });
+ CharSourceRange::getTokenRange(LHS->getSourceRange()), SM,
+ Ctx.getLangOpts()));
+ llvm::erase_if(SourceText,
+ [](unsigned char ch) { return std::isspace(ch); });
InsertEqual = FixItHint::CreateInsertion(InsertLoc, " = " + SourceText);
}
@@ -264,27 +266,27 @@ void BoolBitwiseOperationCheck::emitWarningAndChangeOperatorsIfPossible(
void BoolBitwiseOperationCheck::visitBinaryTreesNode(
const BinaryOperator *BinOp, const BinaryOperator *ParentBinOp,
const clang::SourceManager &SM, clang::ASTContext &Ctx,
- std::optional<bool> &rootAssignsToBoolean) {
+ std::optional<bool> &RootAssignsToBoolean) {
if (!BinOp)
return;
- if (isBooleanBitwise(BinOp, &Ctx, rootAssignsToBoolean))
+ if (isBooleanBitwise(BinOp, &Ctx, RootAssignsToBoolean))
emitWarningAndChangeOperatorsIfPossible(BinOp, ParentBinOp, SM, Ctx);
visitBinaryTreesNode(
dyn_cast<BinaryOperator>(BinOp->getLHS()->IgnoreParenImpCasts()), BinOp,
- SM, Ctx, rootAssignsToBoolean);
+ SM, Ctx, RootAssignsToBoolean);
visitBinaryTreesNode(
dyn_cast<BinaryOperator>(BinOp->getRHS()->IgnoreParenImpCasts()), BinOp,
- SM, Ctx, rootAssignsToBoolean);
+ SM, Ctx, RootAssignsToBoolean);
}
void BoolBitwiseOperationCheck::check(const MatchFinder::MatchResult &Result) {
const auto *binOpRoot = Result.Nodes.getNodeAs<BinaryOperator>("binOpRoot");
const SourceManager &SM = *Result.SourceManager;
ASTContext &Ctx = *Result.Context;
- std::optional<bool> rootAssignsToBoolean = std::nullopt;
- visitBinaryTreesNode(binOpRoot, nullptr, SM, Ctx, rootAssignsToBoolean);
+ std::optional<bool> RootAssignsToBoolean = std::nullopt;
+ visitBinaryTreesNode(binOpRoot, nullptr, SM, Ctx, RootAssignsToBoolean);
}
} // namespace clang::tidy::misc
\ No newline at end of file
diff --git a/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.h b/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.h
index a04188027d3c2..2787b1a1543ee 100644
--- a/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.h
+++ b/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.h
@@ -40,7 +40,7 @@ class BoolBitwiseOperationCheck : public ClangTidyCheck {
const BinaryOperator *ParentBinOp,
const clang::SourceManager &SM,
clang::ASTContext &Ctx,
- std::optional<bool>& rootAssignsToBoolean);
+ std::optional<bool> &rootAssignsToBoolean);
private:
bool StrictMode;
>From 7c6552f01b2c194a2fd5114da1d3ac5b4245470d Mon Sep 17 00:00:00 2001
From: Denis Mikhailov <denismikhaylov38 at gmail.com>
Date: Sat, 8 Nov 2025 22:03:08 +0300
Subject: [PATCH 14/28] fix list.rst
---
clang-tools-extra/docs/clang-tidy/checks/list.rst | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/clang-tools-extra/docs/clang-tidy/checks/list.rst b/clang-tools-extra/docs/clang-tidy/checks/list.rst
index d1344d4c47f8c..865c9cb6e5d48 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/list.rst
+++ b/clang-tools-extra/docs/clang-tidy/checks/list.rst
@@ -174,9 +174,7 @@ Clang-Tidy Checks
:doc:`bugprone-use-after-move <bugprone/use-after-move>`,
:doc:`bugprone-virtual-near-miss <bugprone/virtual-near-miss>`, "Yes"
:doc:`cert-dcl58-cpp <cert/dcl58-cpp>`,
- :doc:`cert-env33-c <cert/env33-c>`,
:doc:`cert-err33-c <cert/err33-c>`,
- :doc:`cert-err52-cpp <cert/err52-cpp>`,
:doc:`cert-err60-cpp <cert/err60-cpp>`,
:doc:`cert-flp30-c <cert/flp30-c>`,
:doc:`cert-mem57-cpp <cert/mem57-cpp>`,
@@ -375,7 +373,7 @@ Clang-Tidy Checks
:doc:`readability-avoid-nested-conditional-operator <readability/avoid-nested-conditional-operator>`,
:doc:`readability-avoid-return-with-void-value <readability/avoid-return-with-void-value>`, "Yes"
:doc:`readability-avoid-unconditional-preprocessor-if <readability/avoid-unconditional-preprocessor-if>`,
- :doc:`readability-braces-around-statements <readability/braces-around-statements>`,
+ :doc:`readability-braces-around-statements <readability/braces-around-statements>`, "Yes"
:doc:`readability-const-return-type <readability/const-return-type>`, "Yes"
:doc:`readability-container-contains <readability/container-contains>`, "Yes"
:doc:`readability-container-data-pointer <readability/container-data-pointer>`, "Yes"
@@ -445,7 +443,9 @@ Check aliases
:doc:`cert-dcl54-cpp <cert/dcl54-cpp>`, :doc:`misc-new-delete-overloads <misc/new-delete-overloads>`,
:doc:`cert-dcl59-cpp <cert/dcl59-cpp>`, :doc:`google-build-namespaces <google/build-namespaces>`,
:doc:`cert-err09-cpp <cert/err09-cpp>`, :doc:`misc-throw-by-value-catch-by-reference <misc/throw-by-value-catch-by-reference>`,
+ :doc:`cert-env33-c <cert/env33-c>`, :doc:`bugprone-command-processor <bugprone/command-processor>`,
:doc:`cert-err34-c <cert/err34-c>`, :doc:`bugprone-unchecked-string-to-number-conversion <bugprone/unchecked-string-to-number-conversion>`,
+ :doc:`cert-err52-cpp <cert/err52-cpp>`, :doc:`modernize-avoid-setjmp-longjmp <modernize/avoid-setjmp-longjmp>`,
:doc:`cert-err58-cpp <cert/err58-cpp>`, :doc:`bugprone-throwing-static-initialization <bugprone/throwing-static-initialization>`,
:doc:`cert-err61-cpp <cert/err61-cpp>`, :doc:`misc-throw-by-value-catch-by-reference <misc/throw-by-value-catch-by-reference>`,
:doc:`cert-exp42-c <cert/exp42-c>`, :doc:`bugprone-suspicious-memory-comparison <bugprone/suspicious-memory-comparison>`,
@@ -572,12 +572,12 @@ Check aliases
:doc:`cppcoreguidelines-non-private-member-variables-in-classes <cppcoreguidelines/non-private-member-variables-in-classes>`, :doc:`misc-non-private-member-variables-in-classes <misc/non-private-member-variables-in-classes>`,
:doc:`cppcoreguidelines-use-default-member-init <cppcoreguidelines/use-default-member-init>`, :doc:`modernize-use-default-member-init <modernize/use-default-member-init>`, "Yes"
:doc:`fuchsia-header-anon-namespaces <fuchsia/header-anon-namespaces>`, :doc:`google-build-namespaces <google/build-namespaces>`,
- :doc:`google-readability-braces-around-statements <google/readability-braces-around-statements>`, :doc:`readability-braces-around-statements <readability/braces-around-statements>`,
+ :doc:`google-readability-braces-around-statements <google/readability-braces-around-statements>`, :doc:`readability-braces-around-statements <readability/braces-around-statements>`, "Yes"
:doc:`google-readability-function-size <google/readability-function-size>`, :doc:`readability-function-size <readability/function-size>`,
:doc:`google-readability-namespace-comments <google/readability-namespace-comments>`, :doc:`llvm-namespace-comment <llvm/namespace-comment>`,
:doc:`hicpp-avoid-c-arrays <hicpp/avoid-c-arrays>`, :doc:`modernize-avoid-c-arrays <modernize/avoid-c-arrays>`,
:doc:`hicpp-avoid-goto <hicpp/avoid-goto>`, :doc:`cppcoreguidelines-avoid-goto <cppcoreguidelines/avoid-goto>`,
- :doc:`hicpp-braces-around-statements <hicpp/braces-around-statements>`, :doc:`readability-braces-around-statements <readability/braces-around-statements>`,
+ :doc:`hicpp-braces-around-statements <hicpp/braces-around-statements>`, :doc:`readability-braces-around-statements <readability/braces-around-statements>`, "Yes"
:doc:`hicpp-deprecated-headers <hicpp/deprecated-headers>`, :doc:`modernize-deprecated-headers <modernize/deprecated-headers>`, "Yes"
:doc:`hicpp-explicit-conversions <hicpp/explicit-conversions>`, :doc:`google-explicit-constructor <google/explicit-constructor>`, "Yes"
:doc:`hicpp-function-size <hicpp/function-size>`, :doc:`readability-function-size <readability/function-size>`,
@@ -602,4 +602,4 @@ Check aliases
:doc:`hicpp-use-override <hicpp/use-override>`, :doc:`modernize-use-override <modernize/use-override>`, "Yes"
:doc:`hicpp-vararg <hicpp/vararg>`, :doc:`cppcoreguidelines-pro-type-vararg <cppcoreguidelines/pro-type-vararg>`,
:doc:`llvm-else-after-return <llvm/else-after-return>`, :doc:`readability-else-after-return <readability/else-after-return>`, "Yes"
- :doc:`llvm-qualified-auto <llvm/qualified-auto>`, :doc:`readability-qualified-auto <readability/qualified-auto>`, "Yes"
+ :doc:`llvm-qualified-auto <llvm/qualified-auto>`, :doc:`readability-qualified-auto <readability/qualified-auto>`, "Yes"
\ No newline at end of file
>From 2aaa9285f51bc45135b901fd68c0f1c508183d18 Mon Sep 17 00:00:00 2001
From: Denis Mikhailov <denismikhaylov38 at gmail.com>
Date: Sun, 9 Nov 2025 02:02:54 +0300
Subject: [PATCH 15/28] Optimize
---
.../misc/BoolBitwiseOperationCheck.cpp | 37 ++++++++++++-------
1 file changed, 23 insertions(+), 14 deletions(-)
diff --git a/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.cpp b/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.cpp
index 748bf889a19e2..60d769e7b9e7d 100644
--- a/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.cpp
+++ b/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.cpp
@@ -74,6 +74,24 @@ static llvm::StringRef translate(llvm::StringRef Value) {
return {};
}
+static bool isBooleanBitwise(const BinaryOperator *BinOp, ASTContext *AC,
+ std::optional<bool> &RootAssignsToBoolean);
+
+static bool recheckIsBooleanDeeply(const BinaryOperator *BinOp, ASTContext *AC,
+ bool &IsBooleanLHS, bool &IsBooleanRHS) {
+ std::optional<bool> DummyFlag = false;
+ IsBooleanLHS = IsBooleanLHS ||
+ isBooleanBitwise(dyn_cast<BinaryOperator>(
+ BinOp->getLHS()->IgnoreParenImpCasts()),
+ AC, DummyFlag);
+ IsBooleanRHS = IsBooleanRHS ||
+ isBooleanBitwise(dyn_cast<BinaryOperator>(
+ BinOp->getRHS()->IgnoreParenImpCasts()),
+ AC, DummyFlag);
+ return true; // just a formal bool for possibility to be invoked from
+ // expression
+}
+
static bool isBooleanBitwise(const BinaryOperator *BinOp, ASTContext *AC,
std::optional<bool> &RootAssignsToBoolean) {
if (!BinOp)
@@ -91,7 +109,9 @@ static bool isBooleanBitwise(const BinaryOperator *BinOp, ASTContext *AC,
->getType()
.getDesugaredType(*AC)
->isBooleanType();
- for (int i = 0; i < 2; ++i) {
+ for (int i = 0; i < 2;
+ !i++ &&
+ recheckIsBooleanDeeply(BinOp, AC, IsBooleanLHS, IsBooleanRHS)) {
if (IsBooleanLHS && IsBooleanRHS) {
RootAssignsToBoolean = RootAssignsToBoolean.value_or(false);
return true;
@@ -105,24 +125,13 @@ static bool isBooleanBitwise(const BinaryOperator *BinOp, ASTContext *AC,
RootAssignsToBoolean = RootAssignsToBoolean.value_or(true);
return true;
}
- std::optional<bool> DummyFlag = false;
- IsBooleanLHS =
- IsBooleanLHS ||
- isBooleanBitwise(dyn_cast<BinaryOperator>(
- BinOp->getLHS()->IgnoreParenImpCasts()),
- AC, DummyFlag);
- IsBooleanRHS =
- IsBooleanRHS ||
- isBooleanBitwise(dyn_cast<BinaryOperator>(
- BinOp->getRHS()->IgnoreParenImpCasts()),
- AC, DummyFlag);
}
}
}
return false;
}
-static const Expr *getValidCompoundsLHS(const BinaryOperator *BinOp) {
+static const Expr *getAcceptableCompoundsLHS(const BinaryOperator *BinOp) {
assert(BinOp->isCompoundAssignmentOp());
if (const auto *DeclRefLHS =
@@ -202,7 +211,7 @@ void BoolBitwiseOperationCheck::emitWarningAndChangeOperatorsIfPossible(
FixItHint InsertEqual;
if (BinOp->isCompoundAssignmentOp()) {
- const auto *LHS = getValidCompoundsLHS(BinOp);
+ const auto *LHS = getAcceptableCompoundsLHS(BinOp);
if (!LHS)
return static_cast<void>(DiagEmitter());
const SourceLocation LocLHS = LHS->getEndLoc();
>From 75a5399deac0599ce9da27a3dadbbee3d7d4f4aa Mon Sep 17 00:00:00 2001
From: Denis Mikhailov <denismikhaylov38 at gmail.com>
Date: Sun, 9 Nov 2025 02:35:11 +0300
Subject: [PATCH 16/28] Fix flags case
---
.../misc/BoolBitwiseOperationCheck.cpp | 63 +++++++++----------
.../misc/bool-bitwise-operation-flags.cpp | 9 +++
2 files changed, 38 insertions(+), 34 deletions(-)
create mode 100644 clang-tools-extra/test/clang-tidy/checkers/misc/bool-bitwise-operation-flags.cpp
diff --git a/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.cpp b/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.cpp
index 60d769e7b9e7d..6ba43af96f8a8 100644
--- a/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.cpp
+++ b/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.cpp
@@ -74,24 +74,6 @@ static llvm::StringRef translate(llvm::StringRef Value) {
return {};
}
-static bool isBooleanBitwise(const BinaryOperator *BinOp, ASTContext *AC,
- std::optional<bool> &RootAssignsToBoolean);
-
-static bool recheckIsBooleanDeeply(const BinaryOperator *BinOp, ASTContext *AC,
- bool &IsBooleanLHS, bool &IsBooleanRHS) {
- std::optional<bool> DummyFlag = false;
- IsBooleanLHS = IsBooleanLHS ||
- isBooleanBitwise(dyn_cast<BinaryOperator>(
- BinOp->getLHS()->IgnoreParenImpCasts()),
- AC, DummyFlag);
- IsBooleanRHS = IsBooleanRHS ||
- isBooleanBitwise(dyn_cast<BinaryOperator>(
- BinOp->getRHS()->IgnoreParenImpCasts()),
- AC, DummyFlag);
- return true; // just a formal bool for possibility to be invoked from
- // expression
-}
-
static bool isBooleanBitwise(const BinaryOperator *BinOp, ASTContext *AC,
std::optional<bool> &RootAssignsToBoolean) {
if (!BinOp)
@@ -109,22 +91,35 @@ static bool isBooleanBitwise(const BinaryOperator *BinOp, ASTContext *AC,
->getType()
.getDesugaredType(*AC)
->isBooleanType();
- for (int i = 0; i < 2;
- !i++ &&
- recheckIsBooleanDeeply(BinOp, AC, IsBooleanLHS, IsBooleanRHS)) {
- if (IsBooleanLHS && IsBooleanRHS) {
- RootAssignsToBoolean = RootAssignsToBoolean.value_or(false);
- return true;
- }
- if (assignsToBoolean(BinOp, AC) ||
- RootAssignsToBoolean.value_or(false)) {
- RootAssignsToBoolean = RootAssignsToBoolean.value_or(true);
- return true;
- }
- if (BinOp->isCompoundAssignmentOp() && IsBooleanLHS) {
- RootAssignsToBoolean = RootAssignsToBoolean.value_or(true);
- return true;
- }
+ if (IsBooleanLHS && IsBooleanRHS) {
+ RootAssignsToBoolean = RootAssignsToBoolean.value_or(false);
+ return true;
+ }
+ if (((IsBooleanLHS || IsBooleanRHS) && assignsToBoolean(BinOp, AC)) ||
+ RootAssignsToBoolean.value_or(false)) {
+ RootAssignsToBoolean = RootAssignsToBoolean.value_or(true);
+ return true;
+ }
+ if (BinOp->isCompoundAssignmentOp() && IsBooleanLHS) {
+ RootAssignsToBoolean = RootAssignsToBoolean.value_or(true);
+ return true;
+ }
+
+ std::optional<bool> DummyFlag = false;
+ IsBooleanLHS =
+ IsBooleanLHS ||
+ isBooleanBitwise(
+ dyn_cast<BinaryOperator>(BinOp->getLHS()->IgnoreParenImpCasts()),
+ AC, DummyFlag);
+ IsBooleanRHS =
+ IsBooleanRHS ||
+ isBooleanBitwise(
+ dyn_cast<BinaryOperator>(BinOp->getRHS()->IgnoreParenImpCasts()),
+ AC, DummyFlag);
+
+ if (IsBooleanLHS && IsBooleanRHS) {
+ RootAssignsToBoolean = RootAssignsToBoolean.value_or(false);
+ return true;
}
}
}
diff --git a/clang-tools-extra/test/clang-tidy/checkers/misc/bool-bitwise-operation-flags.cpp b/clang-tools-extra/test/clang-tidy/checkers/misc/bool-bitwise-operation-flags.cpp
new file mode 100644
index 0000000000000..a7b6af0413484
--- /dev/null
+++ b/clang-tools-extra/test/clang-tidy/checkers/misc/bool-bitwise-operation-flags.cpp
@@ -0,0 +1,9 @@
+// RUN: %check_clang_tidy %s misc-bool-bitwise-operation %t
+
+bool normal() {
+ unsigned flags = 100;
+ if (flags & 0xFFFFFFF8) {
+
+ }
+ return flags & 0x20;
+}
>From c01dfbebebd201c9b4bde2c885733f80ab911390 Mon Sep 17 00:00:00 2001
From: denzor200 <denismikhaylov38 at gmail.com>
Date: Wed, 12 Nov 2025 20:23:50 +0300
Subject: [PATCH 17/28] simplify
---
.../misc/BoolBitwiseOperationCheck.cpp | 11 +---------
...itwise-operation-not-only-bool-operand.cpp | 20 ++-----------------
2 files changed, 3 insertions(+), 28 deletions(-)
diff --git a/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.cpp b/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.cpp
index 6ba43af96f8a8..a19e759ea5263 100644
--- a/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.cpp
+++ b/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.cpp
@@ -35,16 +35,7 @@ static bool assignsToBoolean(const BinaryOperator *BinOp, ASTContext *AC) {
auto Parents = AC->getParents(*BinOp);
for (const auto &Parent : Parents) {
- const auto *ParentNoParen = ignoreParensTowardsTheRoot(&Parent, AC);
- // Special handling for `template<bool bb=true|1>` cases
- if (const auto *D = ParentNoParen->get<Decl>()) {
- if (const auto *NTTPD = dyn_cast<NonTypeTemplateParmDecl>(D)) {
- if (NTTPD->getType().getDesugaredType(*AC)->isBooleanType())
- return true;
- }
- }
-
- if (const auto *S = ParentNoParen->get<Stmt>()) {
+ if (const auto *S = ignoreParensTowardsTheRoot(&Parent, AC)->get<Stmt>()) {
if (const auto *ICE = dyn_cast<ImplicitCastExpr>(S)) {
if (ICE->getType().getDesugaredType(*AC)->isBooleanType())
return true;
diff --git a/clang-tools-extra/test/clang-tidy/checkers/misc/bool-bitwise-operation-not-only-bool-operand.cpp b/clang-tools-extra/test/clang-tidy/checkers/misc/bool-bitwise-operation-not-only-bool-operand.cpp
index e0cd992fa78a4..f93297a42f686 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/misc/bool-bitwise-operation-not-only-bool-operand.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/misc/bool-bitwise-operation-not-only-bool-operand.cpp
@@ -11,9 +11,8 @@ void general(unsigned flags, bool value) {
void take(bool value) {}
-template<bool bb = true | 1>
-// CHECK-MESSAGES: :[[@LINE-1]]:25: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
-// CHECK-FIXES: template<bool bb = true || 1>
+// FIXME: implement `template<bool bb=true|1>` cases
+
void assign_to_boolean(unsigned flags, bool value) {
struct A { bool a = true | 1; };
// CHECK-MESSAGES: :[[@LINE-1]]:30: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
@@ -50,9 +49,6 @@ void assign_to_boolean(unsigned flags, bool value) {
// CHECK-FIXES: result = (flags << 1) || (flags << 2) || (flags << 4) || value;
}
-template<bool bb = (true | 1)>
-// CHECK-MESSAGES: :[[@LINE-1]]:26: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
-// CHECK-FIXES: template<bool bb = (true || 1)>
void assign_to_boolean_parens(unsigned flags, bool value) {
struct A { bool a = (true | 1); };
// CHECK-MESSAGES: :[[@LINE-1]]:31: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
@@ -89,9 +85,6 @@ void assign_to_boolean_parens(unsigned flags, bool value) {
// CHECK-FIXES: result = ((flags << 1) || (flags << 2) || (flags << 4) || value);
}
-template<bool bb = ((true | 1))>
-// CHECK-MESSAGES: :[[@LINE-1]]:27: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
-// CHECK-FIXES: template<bool bb = ((true || 1))>
void assign_to_boolean_parens2(unsigned flags, bool value) {
struct A { bool a = ((true | 1)); };
// CHECK-MESSAGES: :[[@LINE-1]]:32: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
@@ -129,9 +122,6 @@ void assign_to_boolean_parens2(unsigned flags, bool value) {
}
// functional cast
-template<bool bb = bool(true | 1)>
-// CHECK-MESSAGES: :[[@LINE-1]]:30: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
-// CHECK-FIXES: template<bool bb = bool(true || 1)>
void assign_to_boolean_fcast(unsigned flags, bool value) {
struct A { bool a = bool(true | 1); };
// CHECK-MESSAGES: :[[@LINE-1]]:35: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
@@ -169,9 +159,6 @@ void assign_to_boolean_fcast(unsigned flags, bool value) {
}
// C-style cast
-template<bool bb = (bool)(true | 1)>
-// CHECK-MESSAGES: :[[@LINE-1]]:32: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
-// CHECK-FIXES: template<bool bb = (bool)(true || 1)>
void assign_to_boolean_ccast(unsigned flags, bool value) {
struct A { bool a = (bool)(true | 1); };
// CHECK-MESSAGES: :[[@LINE-1]]:37: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
@@ -209,9 +196,6 @@ void assign_to_boolean_ccast(unsigned flags, bool value) {
}
// static_cast
-template<bool bb = static_cast<bool>(true | 1)>
-// CHECK-MESSAGES: :[[@LINE-1]]:43: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
-// CHECK-FIXES: template<bool bb = static_cast<bool>(true || 1)>
void assign_to_boolean_scast(unsigned flags, bool value) {
struct A { bool a = static_cast<bool>(true | 1); };
// CHECK-MESSAGES: :[[@LINE-1]]:48: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
>From af75a05c0fe16ea800aa3baba3afdb72c029281d Mon Sep 17 00:00:00 2001
From: denzor200 <denismikhaylov38 at gmail.com>
Date: Wed, 12 Nov 2025 20:55:49 +0300
Subject: [PATCH 18/28] lint
---
.../misc/BoolBitwiseOperationCheck.cpp | 72 ++++++++++++-------
.../misc/BoolBitwiseOperationCheck.h | 5 +-
2 files changed, 48 insertions(+), 29 deletions(-)
diff --git a/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.cpp b/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.cpp
index a19e759ea5263..043893f904d6c 100644
--- a/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.cpp
+++ b/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.cpp
@@ -123,8 +123,8 @@ static const Expr *getAcceptableCompoundsLHS(const BinaryOperator *BinOp) {
if (const auto *DeclRefLHS =
dyn_cast<DeclRefExpr>(BinOp->getLHS()->IgnoreImpCasts()))
return DeclRefLHS;
- else if (const auto *MemberLHS =
- dyn_cast<MemberExpr>(BinOp->getLHS()->IgnoreImpCasts()))
+ if (const auto *MemberLHS =
+ dyn_cast<MemberExpr>(BinOp->getLHS()->IgnoreImpCasts()))
return MemberLHS;
return nullptr;
@@ -168,50 +168,68 @@ void BoolBitwiseOperationCheck::emitWarningAndChangeOperatorsIfPossible(
.getDesugaredType(Ctx)
.isVolatileQualified();
});
- if (HasVolatileOperand)
- return static_cast<void>(DiagEmitter());
+ if (HasVolatileOperand) {
+ DiagEmitter();
+ return;
+ }
const bool HasSideEffects = BinOp->getRHS()->HasSideEffects(
Ctx, /*IncludePossibleEffects=*/!StrictMode);
- if (HasSideEffects)
- return static_cast<void>(DiagEmitter());
+ if (HasSideEffects) {
+ DiagEmitter();
+ return;
+ }
SourceLocation Loc = BinOp->getOperatorLoc();
- if (Loc.isInvalid() || Loc.isMacroID())
- return static_cast<void>(IgnoreMacros || DiagEmitter());
+ if (Loc.isInvalid() || Loc.isMacroID()) {
+ IgnoreMacros || DiagEmitter();
+ return;
+ }
Loc = SM.getSpellingLoc(Loc);
- if (Loc.isInvalid() || Loc.isMacroID())
- return static_cast<void>(IgnoreMacros || DiagEmitter());
+ if (Loc.isInvalid() || Loc.isMacroID()) {
+ IgnoreMacros || DiagEmitter();
+ return;
+ }
const CharSourceRange TokenRange = CharSourceRange::getTokenRange(Loc);
- if (TokenRange.isInvalid())
- return static_cast<void>(IgnoreMacros || DiagEmitter());
+ if (TokenRange.isInvalid()) {
+ IgnoreMacros || DiagEmitter();
+ return;
+ }
const StringRef FixSpelling =
translate(Lexer::getSourceText(TokenRange, SM, Ctx.getLangOpts()));
- if (FixSpelling.empty())
- return static_cast<void>(DiagEmitter());
+ if (FixSpelling.empty()) {
+ DiagEmitter();
+ return;
+ }
FixItHint InsertEqual;
if (BinOp->isCompoundAssignmentOp()) {
const auto *LHS = getAcceptableCompoundsLHS(BinOp);
- if (!LHS)
- return static_cast<void>(DiagEmitter());
+ if (!LHS) {
+ DiagEmitter();
+ return;
+ }
const SourceLocation LocLHS = LHS->getEndLoc();
- if (LocLHS.isInvalid() || LocLHS.isMacroID())
- return static_cast<void>(IgnoreMacros || DiagEmitter());
+ if (LocLHS.isInvalid() || LocLHS.isMacroID()) {
+ IgnoreMacros || DiagEmitter();
+ return;
+ }
const SourceLocation InsertLoc =
clang::Lexer::getLocForEndOfToken(LocLHS, 0, SM, Ctx.getLangOpts());
- if (InsertLoc.isInvalid() || InsertLoc.isMacroID())
- return static_cast<void>(IgnoreMacros || DiagEmitter());
+ if (InsertLoc.isInvalid() || InsertLoc.isMacroID()) {
+ IgnoreMacros || DiagEmitter();
+ return;
+ }
auto SourceText = static_cast<std::string>(Lexer::getSourceText(
CharSourceRange::getTokenRange(LHS->getSourceRange()), SM,
Ctx.getLangOpts()));
llvm::erase_if(SourceText,
- [](unsigned char ch) { return std::isspace(ch); });
+ [](unsigned char Ch) { return std::isspace(Ch); });
InsertEqual = FixItHint::CreateInsertion(InsertLoc, " = " + SourceText);
}
@@ -238,7 +256,7 @@ void BoolBitwiseOperationCheck::emitWarningAndChangeOperatorsIfPossible(
} else if (BinOp->getOpcode() == BO_AndAssign && RHSOpcode == BO_LOr)
SurroundedExpr = RHS;
- if (SurroundedExpr && isa<ParenExpr>(SurroundedExpr))
+ if (isa_and_nonnull<ParenExpr>(SurroundedExpr))
SurroundedExpr = nullptr;
FixItHint InsertBrace1;
@@ -248,8 +266,10 @@ void BoolBitwiseOperationCheck::emitWarningAndChangeOperatorsIfPossible(
const SourceLocation InsertSecondLoc = clang::Lexer::getLocForEndOfToken(
SurroundedExpr->getEndLoc(), 0, SM, Ctx.getLangOpts());
if (InsertFirstLoc.isInvalid() || InsertFirstLoc.isMacroID() ||
- InsertSecondLoc.isInvalid() || InsertSecondLoc.isMacroID())
- return static_cast<void>(IgnoreMacros || DiagEmitter());
+ InsertSecondLoc.isInvalid() || InsertSecondLoc.isMacroID()) {
+ IgnoreMacros || DiagEmitter();
+ return;
+ }
InsertBrace1 = FixItHint::CreateInsertion(InsertFirstLoc, "(");
InsertBrace2 = FixItHint::CreateInsertion(InsertSecondLoc, ")");
}
@@ -277,11 +297,11 @@ void BoolBitwiseOperationCheck::visitBinaryTreesNode(
}
void BoolBitwiseOperationCheck::check(const MatchFinder::MatchResult &Result) {
- const auto *binOpRoot = Result.Nodes.getNodeAs<BinaryOperator>("binOpRoot");
+ const auto *BinOpRoot = Result.Nodes.getNodeAs<BinaryOperator>("binOpRoot");
const SourceManager &SM = *Result.SourceManager;
ASTContext &Ctx = *Result.Context;
std::optional<bool> RootAssignsToBoolean = std::nullopt;
- visitBinaryTreesNode(binOpRoot, nullptr, SM, Ctx, RootAssignsToBoolean);
+ visitBinaryTreesNode(BinOpRoot, nullptr, SM, Ctx, RootAssignsToBoolean);
}
} // namespace clang::tidy::misc
\ No newline at end of file
diff --git a/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.h b/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.h
index 2787b1a1543ee..017f1053423a2 100644
--- a/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.h
+++ b/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.h
@@ -22,7 +22,7 @@ namespace clang::tidy::misc {
class BoolBitwiseOperationCheck : public ClangTidyCheck {
public:
BoolBitwiseOperationCheck(StringRef Name, ClangTidyContext *Context);
- void storeOptions(ClangTidyOptions::OptionMap &Options) override;
+ void storeOptions(ClangTidyOptions::OptionMap &Opts) override;
void registerMatchers(ast_matchers::MatchFinder *Finder) override;
void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
bool isLanguageVersionSupported(const LangOptions &LangOpts) const override {
@@ -40,9 +40,8 @@ class BoolBitwiseOperationCheck : public ClangTidyCheck {
const BinaryOperator *ParentBinOp,
const clang::SourceManager &SM,
clang::ASTContext &Ctx,
- std::optional<bool> &rootAssignsToBoolean);
+ std::optional<bool> &RootAssignsToBoolean);
-private:
bool StrictMode;
bool IgnoreMacros;
};
>From aaf2612e509e58179b7efa194f852215b4fefca6 Mon Sep 17 00:00:00 2001
From: denzor200 <denismikhaylov38 at gmail.com>
Date: Wed, 12 Nov 2025 21:16:18 +0300
Subject: [PATCH 19/28] Actualize docs
---
.../misc/BoolBitwiseOperationCheck.cpp | 6 ++---
.../misc/BoolBitwiseOperationCheck.h | 2 +-
.../checks/misc/bool-bitwise-operation.rst | 25 +++++++++++++++----
...-operation-change-possible-side-effect.cpp | 2 +-
4 files changed, 25 insertions(+), 10 deletions(-)
diff --git a/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.cpp b/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.cpp
index 043893f904d6c..1507d51320c7c 100644
--- a/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.cpp
+++ b/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.cpp
@@ -133,12 +133,12 @@ static const Expr *getAcceptableCompoundsLHS(const BinaryOperator *BinOp) {
BoolBitwiseOperationCheck::BoolBitwiseOperationCheck(StringRef Name,
ClangTidyContext *Context)
: ClangTidyCheck(Name, Context),
- StrictMode(Options.get("StrictMode", false)),
+ UnsafeMode(Options.get("UnsafeMode", false)),
IgnoreMacros(Options.get("IgnoreMacros", false)) {}
void BoolBitwiseOperationCheck::storeOptions(
ClangTidyOptions::OptionMap &Opts) {
- Options.store(Opts, "StrictMode", StrictMode);
+ Options.store(Opts, "UnsafeMode", UnsafeMode);
Options.store(Opts, "IgnoreMacros", IgnoreMacros);
}
@@ -174,7 +174,7 @@ void BoolBitwiseOperationCheck::emitWarningAndChangeOperatorsIfPossible(
}
const bool HasSideEffects = BinOp->getRHS()->HasSideEffects(
- Ctx, /*IncludePossibleEffects=*/!StrictMode);
+ Ctx, /*IncludePossibleEffects=*/!UnsafeMode);
if (HasSideEffects) {
DiagEmitter();
return;
diff --git a/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.h b/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.h
index 017f1053423a2..082e4b48c27e8 100644
--- a/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.h
+++ b/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.h
@@ -42,7 +42,7 @@ class BoolBitwiseOperationCheck : public ClangTidyCheck {
clang::ASTContext &Ctx,
std::optional<bool> &RootAssignsToBoolean);
- bool StrictMode;
+ bool UnsafeMode;
bool IgnoreMacros;
};
diff --git a/clang-tools-extra/docs/clang-tidy/checks/misc/bool-bitwise-operation.rst b/clang-tools-extra/docs/clang-tidy/checks/misc/bool-bitwise-operation.rst
index e70ac82779644..480f92452f9c4 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/misc/bool-bitwise-operation.rst
+++ b/clang-tools-extra/docs/clang-tidy/checks/misc/bool-bitwise-operation.rst
@@ -14,8 +14,17 @@ to implicit integer conversions and missed short-circuit evaluation.
bool invalid = false;
invalid |= x > limit.x; // warning: use logical operator '||' for boolean semantics instead of bitwise operator '|='
+ // 400 | invalid |= x > limit.x;
+ // | ^~
+ // | = invalid ||
invalid |= y > limit.y; // warning: use logical operator '||' for boolean semantics instead of bitwise operator '|='
+ // 401 | invalid |= y > limit.y;
+ // | ^~
+ // | = invalid ||
invalid |= z > limit.z; // warning: use logical operator '||' for boolean semantics instead of bitwise operator '|='
+ // 402 | invalid |= z > limit.z;
+ // | ^~
+ // | = invalid ||
if (invalid) {
// error handling
}
@@ -33,24 +42,30 @@ instead of using the ``|=`` operator:
// error handling
}
+It is not always a safe transformation though. The following case will warn
+without fix-it to preserve the semantics.
+
+.. code-block:: c++
+
+ volatile bool invalid = false;
+ invalid |= x > limit.x; // warning: use logical operator '||' for boolean semantics instead of bitwise operator '|='
+
Limitations
-----------
-* Bitwise operators inside templates aren't matched.
+* Bitwise operators inside templates aren't guaranteed to match.
.. code-block:: c++
template <typename X>
void f(X a, X b) {
- a | b;
+ a | b; // the warning may not be emited
}
- // even 'f(true, false)' (or similar) won't trigger the warning.
-
Options
-------
-.. option:: StrictMode
+.. option:: UnsafeMode
Enabling this option promotes more fix-it hints even when they might
change evaluation order or skip side effects. Default value is `false`.
diff --git a/clang-tools-extra/test/clang-tidy/checkers/misc/bool-bitwise-operation-change-possible-side-effect.cpp b/clang-tools-extra/test/clang-tidy/checkers/misc/bool-bitwise-operation-change-possible-side-effect.cpp
index a51220be391bc..ee700763136c7 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/misc/bool-bitwise-operation-change-possible-side-effect.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/misc/bool-bitwise-operation-change-possible-side-effect.cpp
@@ -1,6 +1,6 @@
// RUN: %check_clang_tidy %s misc-bool-bitwise-operation %t \
// RUN: -config="{CheckOptions: { \
-// RUN: misc-bool-bitwise-operation.StrictMode: true }}"
+// RUN: misc-bool-bitwise-operation.UnsafeMode: true }}"
bool function_with_possible_side_effects();
>From 96dc087ce530224c0284972cfb642efffe0a66fd Mon Sep 17 00:00:00 2001
From: denzor200 <denismikhaylov38 at gmail.com>
Date: Fri, 14 Nov 2025 01:11:55 +0300
Subject: [PATCH 20/28] review from EugeneZelenko
---
.../clang-tidy/misc/BoolBitwiseOperationCheck.cpp | 2 +-
.../clang-tidy/misc/BoolBitwiseOperationCheck.h | 6 +++---
.../test/clang-tidy/checkers/misc/bool-bitwise-operation.c | 2 +-
3 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.cpp b/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.cpp
index 1507d51320c7c..8d1bc2f18065a 100644
--- a/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.cpp
+++ b/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.cpp
@@ -1,4 +1,4 @@
-//===--- BoolBitwiseOperationCheck.cpp - clang-tidy -----------------------===//
+//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
diff --git a/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.h b/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.h
index 082e4b48c27e8..3725e0b54ebc5 100644
--- a/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.h
+++ b/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.h
@@ -1,4 +1,4 @@
-//===--- BoolBitwiseOperationCheck.h - clang-tidy ---------------*- C++ -*-===//
+//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -18,7 +18,7 @@ namespace clang::tidy::misc {
/// ``&&`` and ``||`` would be more appropriate.
///
/// For the user-facing documentation see:
-/// http://clang.llvm.org/extra/clang-tidy/checks/misc/bool-bitwise-operation.html
+/// https://clang.llvm.org/extra/clang-tidy/checks/misc/bool-bitwise-operation.html
class BoolBitwiseOperationCheck : public ClangTidyCheck {
public:
BoolBitwiseOperationCheck(StringRef Name, ClangTidyContext *Context);
@@ -48,4 +48,4 @@ class BoolBitwiseOperationCheck : public ClangTidyCheck {
} // namespace clang::tidy::misc
-#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MISC_BOOLBITWISEOPERATIONCHECK_H
\ No newline at end of file
+#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MISC_BOOLBITWISEOPERATIONCHECK_H
diff --git a/clang-tools-extra/test/clang-tidy/checkers/misc/bool-bitwise-operation.c b/clang-tools-extra/test/clang-tidy/checkers/misc/bool-bitwise-operation.c
index 0df4b9c4ed680..ebafc19dca605 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/misc/bool-bitwise-operation.c
+++ b/clang-tools-extra/test/clang-tidy/checkers/misc/bool-bitwise-operation.c
@@ -23,4 +23,4 @@ void bad() {
a &= b;
// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '&&' for boolean semantics instead of bitwise operator '&=' [misc-bool-bitwise-operation]
// CHECK-FIXES: a = a && b;
-}
\ No newline at end of file
+}
>From 123aa6385de4d88d5bde4f6d526932df31a43519 Mon Sep 17 00:00:00 2001
From: denzor200 <denismikhaylov38 at gmail.com>
Date: Fri, 14 Nov 2025 01:16:26 +0300
Subject: [PATCH 21/28] more newlines
---
clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.cpp | 2 +-
.../misc/bool-bitwise-operation-change-possible-side-effect.cpp | 2 +-
.../checkers/misc/bool-bitwise-operation-ignore-macros.cpp | 2 +-
.../checkers/misc/bool-bitwise-operation-nontraditional.cpp | 2 +-
4 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.cpp b/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.cpp
index 8d1bc2f18065a..f483888a82bb6 100644
--- a/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.cpp
+++ b/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.cpp
@@ -304,4 +304,4 @@ void BoolBitwiseOperationCheck::check(const MatchFinder::MatchResult &Result) {
visitBinaryTreesNode(BinOpRoot, nullptr, SM, Ctx, RootAssignsToBoolean);
}
-} // namespace clang::tidy::misc
\ No newline at end of file
+} // namespace clang::tidy::misc
diff --git a/clang-tools-extra/test/clang-tidy/checkers/misc/bool-bitwise-operation-change-possible-side-effect.cpp b/clang-tools-extra/test/clang-tidy/checkers/misc/bool-bitwise-operation-change-possible-side-effect.cpp
index ee700763136c7..a39131ec54a8e 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/misc/bool-bitwise-operation-change-possible-side-effect.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/misc/bool-bitwise-operation-change-possible-side-effect.cpp
@@ -79,4 +79,4 @@ void bad_definitely_side_effects() {
a |= b || (acc++, c);
// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|=' [misc-bool-bitwise-operation]
// CHECK-MESSAGES-NOT: :[[@LINE-2]]:{{.*}}: note: FIX-IT applied suggested code changes
-}
\ No newline at end of file
+}
diff --git a/clang-tools-extra/test/clang-tidy/checkers/misc/bool-bitwise-operation-ignore-macros.cpp b/clang-tools-extra/test/clang-tidy/checkers/misc/bool-bitwise-operation-ignore-macros.cpp
index d2b742cf207d1..9980e65fddeaa 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/misc/bool-bitwise-operation-ignore-macros.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/misc/bool-bitwise-operation-ignore-macros.cpp
@@ -50,4 +50,4 @@ void bad_in_macro() {
b &= CAT(a, b);
// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use logical operator '&&' for boolean semantics instead of bitwise operator '&=' [misc-bool-bitwise-operation]
// CHECK-FIXES: b = b && CAT(a, b);
-}
\ No newline at end of file
+}
diff --git a/clang-tools-extra/test/clang-tidy/checkers/misc/bool-bitwise-operation-nontraditional.cpp b/clang-tools-extra/test/clang-tidy/checkers/misc/bool-bitwise-operation-nontraditional.cpp
index 974ebe1f75053..69b090479bad4 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/misc/bool-bitwise-operation-nontraditional.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/misc/bool-bitwise-operation-nontraditional.cpp
@@ -408,4 +408,4 @@ int bad_in_template_lamnda_captured(T a, T b) {
return 0;
}
-int dummy = bad_in_template(true, false) + bad_in_template_lamnda_captured(false, true);
\ No newline at end of file
+int dummy = bad_in_template(true, false) + bad_in_template_lamnda_captured(false, true);
>From aff7d536b036ec307cc7b8e6b4957ce8ba814b45 Mon Sep 17 00:00:00 2001
From: denzor200 <denismikhaylov38 at gmail.com>
Date: Fri, 14 Nov 2025 02:00:42 +0300
Subject: [PATCH 22/28] review from localspook
---
.../clang-tidy/misc/BoolBitwiseOperationCheck.cpp | 10 +++++-----
clang-tools-extra/docs/clang-tidy/checks/list.rst | 2 +-
.../clang-tidy/checks/misc/bool-bitwise-operation.rst | 11 +++++------
.../misc/bool-bitwise-operation-nontraditional.cpp | 4 ++--
.../checkers/misc/bool-bitwise-operation.cpp | 4 ++--
5 files changed, 15 insertions(+), 16 deletions(-)
diff --git a/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.cpp b/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.cpp
index f483888a82bb6..4a83db09e4a88 100644
--- a/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.cpp
+++ b/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.cpp
@@ -22,9 +22,9 @@ static const DynTypedNode *ignoreParensTowardsTheRoot(const DynTypedNode *N,
if (const auto *S = N->get<Stmt>()) {
if (isa<ParenExpr>(S)) {
auto Parents = AC->getParents(*S);
- for (const auto &Parent : Parents) {
- return ignoreParensTowardsTheRoot(&Parent, AC);
- }
+ // FIXME: do we need to consider all `Parents` ?
+ if (!Parents.empty())
+ return ignoreParensTowardsTheRoot(&Parents[0], AC);
}
}
return N;
@@ -46,7 +46,7 @@ static bool assignsToBoolean(const BinaryOperator *BinOp, ASTContext *AC) {
return false;
}
-constexpr std::array<std::pair<llvm::StringRef, llvm::StringRef>, 8U>
+static constexpr std::array<std::pair<StringRef, StringRef>, 8U>
OperatorsTransformation{{{"|", "||"},
{"|=", "||"},
{"&", "&&"},
@@ -56,7 +56,7 @@ constexpr std::array<std::pair<llvm::StringRef, llvm::StringRef>, 8U>
{"bitor", "or"},
{"or_eq", "or"}}};
-static llvm::StringRef translate(llvm::StringRef Value) {
+static StringRef translate(StringRef Value) {
for (const auto &[Bitwise, Logical] : OperatorsTransformation) {
if (Value == Bitwise)
return Logical;
diff --git a/clang-tools-extra/docs/clang-tidy/checks/list.rst b/clang-tools-extra/docs/clang-tidy/checks/list.rst
index 3e14aee287d64..a1b7ab5eeb90f 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/list.rst
+++ b/clang-tools-extra/docs/clang-tidy/checks/list.rst
@@ -609,4 +609,4 @@ Check aliases
:doc:`hicpp-use-override <hicpp/use-override>`, :doc:`modernize-use-override <modernize/use-override>`, "Yes"
:doc:`hicpp-vararg <hicpp/vararg>`, :doc:`cppcoreguidelines-pro-type-vararg <cppcoreguidelines/pro-type-vararg>`,
:doc:`llvm-else-after-return <llvm/else-after-return>`, :doc:`readability-else-after-return <readability/else-after-return>`, "Yes"
- :doc:`llvm-qualified-auto <llvm/qualified-auto>`, :doc:`readability-qualified-auto <readability/qualified-auto>`, "Yes"
\ No newline at end of file
+ :doc:`llvm-qualified-auto <llvm/qualified-auto>`, :doc:`readability-qualified-auto <readability/qualified-auto>`, "Yes"
diff --git a/clang-tools-extra/docs/clang-tidy/checks/misc/bool-bitwise-operation.rst b/clang-tools-extra/docs/clang-tidy/checks/misc/bool-bitwise-operation.rst
index 480f92452f9c4..5dd8ff6d68374 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/misc/bool-bitwise-operation.rst
+++ b/clang-tools-extra/docs/clang-tidy/checks/misc/bool-bitwise-operation.rst
@@ -59,7 +59,7 @@ Limitations
template <typename X>
void f(X a, X b) {
- a | b; // the warning may not be emited
+ a | b; // the warning may not be emitted
}
Options
@@ -67,11 +67,10 @@ Options
.. option:: UnsafeMode
- Enabling this option promotes more fix-it hints even when they might
- change evaluation order or skip side effects. Default value is `false`.
+ Promotes more fix-it hints even when they might change evaluation order or
+ skip side effects. Default value is `false`.
.. option:: IgnoreMacros
- This option disables the warning if a macro inside the expression body
- prevents replacing a bitwise operator with a logical one. Default value
- is `false`.
\ No newline at end of file
+ Don't warn if a macro inside the expression body prevents replacing a
+ bitwise operator with a logical one. Default value is `false`.
\ No newline at end of file
diff --git a/clang-tools-extra/test/clang-tidy/checkers/misc/bool-bitwise-operation-nontraditional.cpp b/clang-tools-extra/test/clang-tidy/checkers/misc/bool-bitwise-operation-nontraditional.cpp
index 69b090479bad4..c6a8a7810c93b 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/misc/bool-bitwise-operation-nontraditional.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/misc/bool-bitwise-operation-nontraditional.cpp
@@ -396,7 +396,7 @@ int bad_in_template(T a, T b) {
}
template<typename T>
-int bad_in_template_lamnda_captured(T a, T b) {
+int bad_in_template_lambda_captured(T a, T b) {
[=] mutable {
bool c = false;
// FIXME: at least warning should be provided in these cases
@@ -408,4 +408,4 @@ int bad_in_template_lamnda_captured(T a, T b) {
return 0;
}
-int dummy = bad_in_template(true, false) + bad_in_template_lamnda_captured(false, true);
+int dummy = bad_in_template(true, false) + bad_in_template_lambda_captured(false, true);
diff --git a/clang-tools-extra/test/clang-tidy/checkers/misc/bool-bitwise-operation.cpp b/clang-tools-extra/test/clang-tidy/checkers/misc/bool-bitwise-operation.cpp
index 07bc14c204004..519ba32b9f3c1 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/misc/bool-bitwise-operation.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/misc/bool-bitwise-operation.cpp
@@ -394,7 +394,7 @@ int bad_in_template(T a, T b) {
}
template<typename T>
-int bad_in_template_lamnda_captured(T a, T b) {
+int bad_in_template_lambda_captured(T a, T b) {
[=] mutable {
bool c = false;
// FIXME: at least warning should be provided in these cases
@@ -406,4 +406,4 @@ int bad_in_template_lamnda_captured(T a, T b) {
return 0;
}
-int dummy = bad_in_template(true, false) + bad_in_template_lamnda_captured(false, true);
\ No newline at end of file
+int dummy = bad_in_template(true, false) + bad_in_template_lambda_captured(false, true);
\ No newline at end of file
>From 52066b75927ab622d1e50115a2b57366891a96bc Mon Sep 17 00:00:00 2001
From: denzor200 <denismikhaylov38 at gmail.com>
Date: Fri, 14 Nov 2025 02:07:21 +0300
Subject: [PATCH 23/28] review
---
.../docs/clang-tidy/checks/misc/bool-bitwise-operation.rst | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/clang-tools-extra/docs/clang-tidy/checks/misc/bool-bitwise-operation.rst b/clang-tools-extra/docs/clang-tidy/checks/misc/bool-bitwise-operation.rst
index 5dd8ff6d68374..f7f03575ae126 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/misc/bool-bitwise-operation.rst
+++ b/clang-tools-extra/docs/clang-tidy/checks/misc/bool-bitwise-operation.rst
@@ -67,7 +67,7 @@ Options
.. option:: UnsafeMode
- Promotes more fix-it hints even when they might change evaluation order or
+ Provide more fix-it hints even when they might change evaluation order or
skip side effects. Default value is `false`.
.. option:: IgnoreMacros
>From a4c4487a22b39e2e2d0733491d7b5dbc9605c758 Mon Sep 17 00:00:00 2001
From: denzor200 <denismikhaylov38 at gmail.com>
Date: Fri, 14 Nov 2025 02:12:15 +0300
Subject: [PATCH 24/28] more newlines
---
.../test/clang-tidy/checkers/misc/bool-bitwise-operation.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/clang-tools-extra/test/clang-tidy/checkers/misc/bool-bitwise-operation.cpp b/clang-tools-extra/test/clang-tidy/checkers/misc/bool-bitwise-operation.cpp
index 519ba32b9f3c1..6487026b07583 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/misc/bool-bitwise-operation.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/misc/bool-bitwise-operation.cpp
@@ -406,4 +406,4 @@ int bad_in_template_lambda_captured(T a, T b) {
return 0;
}
-int dummy = bad_in_template(true, false) + bad_in_template_lambda_captured(false, true);
\ No newline at end of file
+int dummy = bad_in_template(true, false) + bad_in_template_lambda_captured(false, true);
>From 7c069dace162958d941200de5d0fbc5e1bf8a920 Mon Sep 17 00:00:00 2001
From: denzor200 <denismikhaylov38 at gmail.com>
Date: Fri, 14 Nov 2025 20:04:45 +0300
Subject: [PATCH 25/28] any_of
---
.../clang-tidy/misc/BoolBitwiseOperationCheck.cpp | 15 +++++----------
1 file changed, 5 insertions(+), 10 deletions(-)
diff --git a/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.cpp b/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.cpp
index 4a83db09e4a88..5d1b7d86f6c51 100644
--- a/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.cpp
+++ b/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.cpp
@@ -34,16 +34,11 @@ static bool assignsToBoolean(const BinaryOperator *BinOp, ASTContext *AC) {
TraversalKindScope RAII(*AC, TK_AsIs);
auto Parents = AC->getParents(*BinOp);
- for (const auto &Parent : Parents) {
- if (const auto *S = ignoreParensTowardsTheRoot(&Parent, AC)->get<Stmt>()) {
- if (const auto *ICE = dyn_cast<ImplicitCastExpr>(S)) {
- if (ICE->getType().getDesugaredType(*AC)->isBooleanType())
- return true;
- }
- }
- }
-
- return false;
+ return llvm::any_of(Parents, [&](const DynTypedNode &Parent) {
+ const auto *S = ignoreParensTowardsTheRoot(&Parent, AC)->get<Stmt>();
+ const auto *ICE = dyn_cast_if_present<ImplicitCastExpr>(S);
+ return ICE ? ICE->getType().getDesugaredType(*AC)->isBooleanType() : false;
+ });
}
static constexpr std::array<std::pair<StringRef, StringRef>, 8U>
>From 4e7cdc4f1073d0e70f3ca533f1f1c9a35a3cf617 Mon Sep 17 00:00:00 2001
From: denzor200 <denismikhaylov38 at gmail.com>
Date: Thu, 20 Nov 2025 21:29:42 +0300
Subject: [PATCH 26/28] review
---
.../misc/BoolBitwiseOperationCheck.cpp | 108 ++++++++----------
1 file changed, 49 insertions(+), 59 deletions(-)
diff --git a/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.cpp b/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.cpp
index 5d1b7d86f6c51..fe3bac73b7c90 100644
--- a/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.cpp
+++ b/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.cpp
@@ -19,13 +19,11 @@ namespace clang::tidy::misc {
static const DynTypedNode *ignoreParensTowardsTheRoot(const DynTypedNode *N,
ASTContext *AC) {
- if (const auto *S = N->get<Stmt>()) {
- if (isa<ParenExpr>(S)) {
- auto Parents = AC->getParents(*S);
- // FIXME: do we need to consider all `Parents` ?
- if (!Parents.empty())
- return ignoreParensTowardsTheRoot(&Parents[0], AC);
- }
+ if (const auto *S = N->get<Stmt>(); isa_and_nonnull<ParenExpr>(S)) {
+ auto Parents = AC->getParents(*S);
+ // FIXME: do we need to consider all `Parents` ?
+ if (!Parents.empty())
+ return ignoreParensTowardsTheRoot(&Parents[0], AC);
}
return N;
}
@@ -65,64 +63,56 @@ static bool isBooleanBitwise(const BinaryOperator *BinOp, ASTContext *AC,
if (!BinOp)
return false;
- for (const auto &[Bitwise, _] : OperatorsTransformation) {
- if (BinOp->getOpcodeStr() == Bitwise) {
- bool IsBooleanLHS = BinOp->getLHS()
- ->IgnoreImpCasts()
- ->getType()
- .getDesugaredType(*AC)
- ->isBooleanType();
- bool IsBooleanRHS = BinOp->getRHS()
- ->IgnoreImpCasts()
- ->getType()
- .getDesugaredType(*AC)
- ->isBooleanType();
- if (IsBooleanLHS && IsBooleanRHS) {
- RootAssignsToBoolean = RootAssignsToBoolean.value_or(false);
- return true;
- }
- if (((IsBooleanLHS || IsBooleanRHS) && assignsToBoolean(BinOp, AC)) ||
- RootAssignsToBoolean.value_or(false)) {
- RootAssignsToBoolean = RootAssignsToBoolean.value_or(true);
- return true;
- }
- if (BinOp->isCompoundAssignmentOp() && IsBooleanLHS) {
- RootAssignsToBoolean = RootAssignsToBoolean.value_or(true);
- return true;
- }
-
- std::optional<bool> DummyFlag = false;
- IsBooleanLHS =
- IsBooleanLHS ||
- isBooleanBitwise(
- dyn_cast<BinaryOperator>(BinOp->getLHS()->IgnoreParenImpCasts()),
- AC, DummyFlag);
- IsBooleanRHS =
- IsBooleanRHS ||
- isBooleanBitwise(
- dyn_cast<BinaryOperator>(BinOp->getRHS()->IgnoreParenImpCasts()),
- AC, DummyFlag);
-
- if (IsBooleanLHS && IsBooleanRHS) {
- RootAssignsToBoolean = RootAssignsToBoolean.value_or(false);
- return true;
- }
- }
+ if (!llvm::is_contained(llvm::make_first_range(OperatorsTransformation), BinOp->getOpcodeStr()))
+ return false;
+
+ bool IsBooleanLHS = BinOp->getLHS()
+ ->IgnoreImpCasts()
+ ->getType()
+ .getDesugaredType(*AC)
+ ->isBooleanType();
+ bool IsBooleanRHS = BinOp->getRHS()
+ ->IgnoreImpCasts()
+ ->getType()
+ .getDesugaredType(*AC)
+ ->isBooleanType();
+ if (IsBooleanLHS && IsBooleanRHS) {
+ RootAssignsToBoolean = RootAssignsToBoolean.value_or(false);
+ return true;
+ }
+ if (((IsBooleanLHS || IsBooleanRHS) && assignsToBoolean(BinOp, AC)) ||
+ RootAssignsToBoolean.value_or(false)) {
+ RootAssignsToBoolean = RootAssignsToBoolean.value_or(true);
+ return true;
+ }
+ if (BinOp->isCompoundAssignmentOp() && IsBooleanLHS) {
+ RootAssignsToBoolean = RootAssignsToBoolean.value_or(true);
+ return true;
+ }
+
+ std::optional<bool> DummyFlag = false;
+ IsBooleanLHS =
+ IsBooleanLHS ||
+ isBooleanBitwise(
+ dyn_cast<BinaryOperator>(BinOp->getLHS()->IgnoreParenImpCasts()),
+ AC, DummyFlag);
+ IsBooleanRHS =
+ IsBooleanRHS ||
+ isBooleanBitwise(
+ dyn_cast<BinaryOperator>(BinOp->getRHS()->IgnoreParenImpCasts()),
+ AC, DummyFlag);
+
+ if (IsBooleanLHS && IsBooleanRHS) {
+ RootAssignsToBoolean = RootAssignsToBoolean.value_or(false);
+ return true;
}
return false;
}
static const Expr *getAcceptableCompoundsLHS(const BinaryOperator *BinOp) {
assert(BinOp->isCompoundAssignmentOp());
-
- if (const auto *DeclRefLHS =
- dyn_cast<DeclRefExpr>(BinOp->getLHS()->IgnoreImpCasts()))
- return DeclRefLHS;
- if (const auto *MemberLHS =
- dyn_cast<MemberExpr>(BinOp->getLHS()->IgnoreImpCasts()))
- return MemberLHS;
-
- return nullptr;
+ const Expr *LHS = BinOp->getLHS()->IgnoreImpCasts();
+ return isa<DeclRefExpr, MemberExpr>(LHS) ? LHS : nullptr;
}
BoolBitwiseOperationCheck::BoolBitwiseOperationCheck(StringRef Name,
>From b3af19666ca724858cd314affbde3ff38105eda5 Mon Sep 17 00:00:00 2001
From: denzor200 <denismikhaylov38 at gmail.com>
Date: Thu, 20 Nov 2025 21:41:10 +0300
Subject: [PATCH 27/28] format
---
.../misc/BoolBitwiseOperationCheck.cpp | 21 +++++++++----------
1 file changed, 10 insertions(+), 11 deletions(-)
diff --git a/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.cpp b/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.cpp
index fe3bac73b7c90..4fe8460d01eec 100644
--- a/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.cpp
+++ b/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.cpp
@@ -63,7 +63,8 @@ static bool isBooleanBitwise(const BinaryOperator *BinOp, ASTContext *AC,
if (!BinOp)
return false;
- if (!llvm::is_contained(llvm::make_first_range(OperatorsTransformation), BinOp->getOpcodeStr()))
+ if (!llvm::is_contained(llvm::make_first_range(OperatorsTransformation),
+ BinOp->getOpcodeStr()))
return false;
bool IsBooleanLHS = BinOp->getLHS()
@@ -91,16 +92,14 @@ static bool isBooleanBitwise(const BinaryOperator *BinOp, ASTContext *AC,
}
std::optional<bool> DummyFlag = false;
- IsBooleanLHS =
- IsBooleanLHS ||
- isBooleanBitwise(
- dyn_cast<BinaryOperator>(BinOp->getLHS()->IgnoreParenImpCasts()),
- AC, DummyFlag);
- IsBooleanRHS =
- IsBooleanRHS ||
- isBooleanBitwise(
- dyn_cast<BinaryOperator>(BinOp->getRHS()->IgnoreParenImpCasts()),
- AC, DummyFlag);
+ IsBooleanLHS = IsBooleanLHS ||
+ isBooleanBitwise(dyn_cast<BinaryOperator>(
+ BinOp->getLHS()->IgnoreParenImpCasts()),
+ AC, DummyFlag);
+ IsBooleanRHS = IsBooleanRHS ||
+ isBooleanBitwise(dyn_cast<BinaryOperator>(
+ BinOp->getRHS()->IgnoreParenImpCasts()),
+ AC, DummyFlag);
if (IsBooleanLHS && IsBooleanRHS) {
RootAssignsToBoolean = RootAssignsToBoolean.value_or(false);
>From d0a3b18b2d8645aa38ba06e5cabc243ece4c25fc Mon Sep 17 00:00:00 2001
From: denzor200 <denismikhaylov38 at gmail.com>
Date: Sat, 22 Nov 2025 00:15:00 +0300
Subject: [PATCH 28/28] review
---
.../misc/BoolBitwiseOperationCheck.cpp | 19 +++++++++----------
1 file changed, 9 insertions(+), 10 deletions(-)
diff --git a/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.cpp b/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.cpp
index 4fe8460d01eec..7b1a70cfb3885 100644
--- a/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.cpp
+++ b/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.cpp
@@ -67,16 +67,15 @@ static bool isBooleanBitwise(const BinaryOperator *BinOp, ASTContext *AC,
BinOp->getOpcodeStr()))
return false;
- bool IsBooleanLHS = BinOp->getLHS()
- ->IgnoreImpCasts()
- ->getType()
- .getDesugaredType(*AC)
- ->isBooleanType();
- bool IsBooleanRHS = BinOp->getRHS()
- ->IgnoreImpCasts()
- ->getType()
- .getDesugaredType(*AC)
- ->isBooleanType();
+ const auto isBooleanType = [&AC](const Expr *expr) -> bool {
+ return expr->IgnoreImpCasts()
+ ->getType()
+ .getDesugaredType(*AC)
+ ->isBooleanType();
+ };
+
+ bool IsBooleanLHS = isBooleanType(BinOp->getLHS());
+ bool IsBooleanRHS = isBooleanType(BinOp->getRHS());
if (IsBooleanLHS && IsBooleanRHS) {
RootAssignsToBoolean = RootAssignsToBoolean.value_or(false);
return true;
More information about the cfe-commits
mailing list