[clang-tools-extra] [clang-tidy] Add misc-bool-bitwise-operation check (PR #167552)

Denis Mikhailov via cfe-commits cfe-commits at lists.llvm.org
Sat Jan 17 05:31:08 PST 2026


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/49] 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/49] 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/49] 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/49] 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/49] 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/49] 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/49] 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/49] 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/49] 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/49] 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/49] 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/49] 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/49] 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/49] 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/49] 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/49] 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/49] 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/49] 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/49] 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/49] 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/49] 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/49] 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/49] 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/49] 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/49] 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/49] 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/49] 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/49] 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;

>From e33511632a9dcaedbbaf14499624cfc2e6bb1f72 Mon Sep 17 00:00:00 2001
From: Denis Mikhailov <denismikhaylov38 at gmail.com>
Date: Sat, 22 Nov 2025 00:53:02 +0300
Subject: [PATCH 29/49] Update BoolBitwiseOperationCheck.cpp

---
 .../clang-tidy/misc/BoolBitwiseOperationCheck.cpp      | 10 +++++-----
 1 file 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 7b1a70cfb3885..2771f81e97283 100644
--- a/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.cpp
+++ b/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.cpp
@@ -29,7 +29,7 @@ static const DynTypedNode *ignoreParensTowardsTheRoot(const DynTypedNode *N,
 }
 
 static bool assignsToBoolean(const BinaryOperator *BinOp, ASTContext *AC) {
-  TraversalKindScope RAII(*AC, TK_AsIs);
+  const TraversalKindScope RAII(*AC, TK_AsIs);
   auto Parents = AC->getParents(*BinOp);
 
   return llvm::any_of(Parents, [&](const DynTypedNode &Parent) {
@@ -67,15 +67,15 @@ static bool isBooleanBitwise(const BinaryOperator *BinOp, ASTContext *AC,
                           BinOp->getOpcodeStr()))
     return false;
 
-  const auto isBooleanType = [&AC](const Expr *expr) -> bool {
-    return expr->IgnoreImpCasts()
+  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());
+  bool IsBooleanLHS = IsBooleanType(BinOp->getLHS());
+  bool IsBooleanRHS = IsBooleanType(BinOp->getRHS());
   if (IsBooleanLHS && IsBooleanRHS) {
     RootAssignsToBoolean = RootAssignsToBoolean.value_or(false);
     return true;

>From 6e09d72a7100ebfe5226b7a589aca7b316bb7a29 Mon Sep 17 00:00:00 2001
From: denzor200 <denismikhaylov38 at gmail.com>
Date: Sun, 28 Dec 2025 05:47:44 +0300
Subject: [PATCH 30/49] reimplement to use DynamicRecursiveASTVisitor

---
 .../misc/BoolBitwiseOperationCheck.cpp        | 74 +++++++++++++++----
 .../misc/BoolBitwiseOperationCheck.h          |  7 +-
 2 files changed, 59 insertions(+), 22 deletions(-)

diff --git a/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.cpp b/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.cpp
index 2771f81e97283..e8b096754890d 100644
--- a/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.cpp
+++ b/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.cpp
@@ -7,11 +7,13 @@
 //===----------------------------------------------------------------------===//
 
 #include "BoolBitwiseOperationCheck.h"
+#include "clang/AST/DynamicRecursiveASTVisitor.h"
 #include "clang/ASTMatchers/ASTMatchFinder.h"
 #include "clang/Lex/Lexer.h"
 #include <array>
 #include <optional>
 #include <utility>
+#include <vector>
 
 using namespace clang::ast_matchers;
 
@@ -261,30 +263,70 @@ void BoolBitwiseOperationCheck::emitWarningAndChangeOperatorsIfPossible(
                 << InsertBrace2;
 }
 
-void BoolBitwiseOperationCheck::visitBinaryTreesNode(
-    const BinaryOperator *BinOp, const BinaryOperator *ParentBinOp,
-    const clang::SourceManager &SM, clang::ASTContext &Ctx,
-    std::optional<bool> &RootAssignsToBoolean) {
-  if (!BinOp)
-    return;
+namespace {
+class BinaryOperatorVisitor : public clang::DynamicRecursiveASTVisitor {
+  clang::tidy::misc::BoolBitwiseOperationCheck &Check;
+  const clang::SourceManager &SM;
+  clang::ASTContext &Ctx;
+  std::optional<bool> &RootAssignsToBoolean;
+  // Stack to track parent binary operators during traversal
+  std::vector<const clang::BinaryOperator *> ParentStack;
+
+public:
+  BinaryOperatorVisitor(clang::tidy::misc::BoolBitwiseOperationCheck &Check,
+                        const clang::SourceManager &SM,
+                        clang::ASTContext &Ctx,
+                        std::optional<bool> &RootAssignsToBoolean)
+      : Check(Check), SM(SM), Ctx(Ctx),
+        RootAssignsToBoolean(RootAssignsToBoolean) {}
+
+  bool TraverseBinaryOperator(clang::BinaryOperator *BinOp) override {
+    if (!BinOp)
+      return true;
+
+    // Check if this BinOp is a direct child of the parent in the stack.
+    // If not, we skip processing it (don't add to stack).
+    if (!ParentStack.empty() && !(ParentStack.back()->getLHS()->IgnoreParenImpCasts() == BinOp || ParentStack.back()->getRHS()->IgnoreParenImpCasts() == BinOp)) {
+      return true;
+    }
 
-  if (isBooleanBitwise(BinOp, &Ctx, RootAssignsToBoolean))
-    emitWarningAndChangeOperatorsIfPossible(BinOp, ParentBinOp, SM, Ctx);
+    // Push current binary operator as parent for children
+    ParentStack.push_back(BinOp);
+    // Traverse children
+    bool Result = clang::DynamicRecursiveASTVisitor::TraverseBinaryOperator(BinOp);
+    // Pop after traversal
+    ParentStack.pop_back();
+    return Result;
+  }
 
-  visitBinaryTreesNode(
-      dyn_cast<BinaryOperator>(BinOp->getLHS()->IgnoreParenImpCasts()), BinOp,
-      SM, Ctx, RootAssignsToBoolean);
-  visitBinaryTreesNode(
-      dyn_cast<BinaryOperator>(BinOp->getRHS()->IgnoreParenImpCasts()), BinOp,
-      SM, Ctx, RootAssignsToBoolean);
-}
+  bool VisitBinaryOperator(clang::BinaryOperator *BinOp) override {
+    if (!BinOp)
+      return true;
+
+    const clang::BinaryOperator *ParentBinOp =
+        ParentStack.size() < 2 ? nullptr : ParentStack[ParentStack.size() - 2];
+
+    if (isBooleanBitwise(BinOp, &Ctx, RootAssignsToBoolean))
+      Check.emitWarningAndChangeOperatorsIfPossible(BinOp, ParentBinOp, SM,
+                                                    Ctx);
+
+    return true;
+  }
+};
+} // namespace
 
 void BoolBitwiseOperationCheck::check(const MatchFinder::MatchResult &Result) {
   const auto *BinOpRoot = Result.Nodes.getNodeAs<BinaryOperator>("binOpRoot");
+  if (!BinOpRoot)
+    return;
+
   const SourceManager &SM = *Result.SourceManager;
   ASTContext &Ctx = *Result.Context;
   std::optional<bool> RootAssignsToBoolean = std::nullopt;
-  visitBinaryTreesNode(BinOpRoot, nullptr, SM, Ctx, RootAssignsToBoolean);
+
+  BinaryOperatorVisitor Visitor(*this, SM, Ctx, RootAssignsToBoolean);
+  // TraverseStmt requires non-const pointer, but we're only reading
+  Visitor.TraverseStmt(const_cast<BinaryOperator *>(BinOpRoot));
 }
 
 } // namespace clang::tidy::misc
diff --git a/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.h b/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.h
index 3725e0b54ebc5..4a3b36a12302b 100644
--- a/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.h
+++ b/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.h
@@ -32,16 +32,11 @@ 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,
-                            std::optional<bool> &RootAssignsToBoolean);
 
+private:
   bool UnsafeMode;
   bool IgnoreMacros;
 };

>From 754514f99c5849b8b8f8dbcb73688ef43373c6aa Mon Sep 17 00:00:00 2001
From: denzor200 <denismikhaylov38 at gmail.com>
Date: Mon, 29 Dec 2025 05:59:44 +0300
Subject: [PATCH 31/49] Simplify isBooleanBitwise

---
 .../misc/BoolBitwiseOperationCheck.cpp        | 90 +++++++++++++------
 1 file changed, 61 insertions(+), 29 deletions(-)

diff --git a/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.cpp b/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.cpp
index e8b096754890d..c89a956c184dd 100644
--- a/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.cpp
+++ b/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.cpp
@@ -60,52 +60,82 @@ static StringRef translate(StringRef Value) {
   return {};
 }
 
+static bool isBitwiseOperation(StringRef Value) {
+  return llvm::is_contained(llvm::make_first_range(OperatorsTransformation),
+                            Value);
+}
+
+/// Checks if a binary operator is a bitwise operation that should be treated
+/// as a boolean operation (i.e., should use logical operators instead).
+///
+/// This function determines whether a bitwise operation (|, &, |=, &=, etc.)
+/// is being used in a boolean context, which typically indicates the case where
+/// logical operators (||, &&) should have been used instead.
+///
+/// \param BinOp The binary operator to check. Must not be null.
+/// \param AC The AST context for type checking and parent traversal.
+/// \param RootAssignsToBoolean An output parameter that tracks whether the
+///        root binary operator in the expression tree assigns to a boolean
+///        type. This is used to propagate the assignment context through
+///        nested binary operations. The value is set to true if any operation
+///        in the chain assigns to boolean, false if both operands are boolean
+///        but no assignment occurs, and remains unset if the operation is not
+///        boolean bitwise.
+///
+/// \returns true if the operation is a bitwise operation used in a boolean
+///          context (both operands are boolean, or it assigns to boolean),
+///          false otherwise.
 static bool isBooleanBitwise(const BinaryOperator *BinOp, ASTContext *AC,
                              std::optional<bool> &RootAssignsToBoolean) {
   if (!BinOp)
     return false;
 
-  if (!llvm::is_contained(llvm::make_first_range(OperatorsTransformation),
-                          BinOp->getOpcodeStr()))
+  if (!isBitwiseOperation(BinOp->getOpcodeStr()))
     return false;
 
+  // Lambda to check if an expression is boolean type, either directly or
+  // recursively through nested binary operators. This handles cases like
+  // `(a | b) & c` where the LHS is itself a boolean bitwise operation.
   const auto IsBooleanType = [&AC](const Expr *Expr) -> bool {
-    return Expr->IgnoreImpCasts()
-        ->getType()
-        .getDesugaredType(*AC)
-        ->isBooleanType();
+    if (Expr->IgnoreImpCasts()
+            ->getType()
+            .getDesugaredType(*AC)
+            ->isBooleanType())
+      return true;
+    std::optional<bool> DummyFlag = false;
+    return isBooleanBitwise(dyn_cast<BinaryOperator>(
+                                Expr->IgnoreParenImpCasts()),
+                            AC, DummyFlag);
   };
 
-  bool IsBooleanLHS = IsBooleanType(BinOp->getLHS());
-  bool IsBooleanRHS = IsBooleanType(BinOp->getRHS());
+  const bool IsBooleanLHS = IsBooleanType(BinOp->getLHS());
+  const bool IsBooleanRHS = IsBooleanType(BinOp->getRHS());
+
+  // If both operands are boolean, this is definitely a boolean bitwise
+  // operation. Preserve the existing RootAssignsToBoolean value if set,
+  // otherwise set it to false (no assignment context).
   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) {
+
+  // Check if this operation assigns to a boolean type. This includes:
+  // 1. Operations where at least one operand is boolean and the result is
+  //    assigned to boolean (e.g., `bool x = a | b` where a is int and b is boolean)
+  // 2. Compound assignments where the LHS is boolean (e.g., `x |= y` where y is int and x is boolean)
+  const bool IsRelevantAssignmentToBoolean = 
+    ((IsBooleanLHS || IsBooleanRHS) && assignsToBoolean(BinOp, AC)) ||
+    (BinOp->isCompoundAssignmentOp() && IsBooleanLHS);
+
+  // If this operation assigns to boolean, or if we've already determined that
+  // the root assigns to boolean (from a nested operation), then this is a
+  // boolean bitwise operation. Set RootAssignsToBoolean to true to propagate
+  // this information up the call stack.
+  if (IsRelevantAssignmentToBoolean || RootAssignsToBoolean.value_or(false)) {
     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;
 }
 
@@ -306,9 +336,11 @@ class BinaryOperatorVisitor : public clang::DynamicRecursiveASTVisitor {
     const clang::BinaryOperator *ParentBinOp =
         ParentStack.size() < 2 ? nullptr : ParentStack[ParentStack.size() - 2];
 
-    if (isBooleanBitwise(BinOp, &Ctx, RootAssignsToBoolean))
+    if (isBooleanBitwise(BinOp, &Ctx, RootAssignsToBoolean)) {
+      assert(RootAssignsToBoolean.has_value());
       Check.emitWarningAndChangeOperatorsIfPossible(BinOp, ParentBinOp, SM,
                                                     Ctx);
+    }
 
     return true;
   }

>From 461da1bbb1572832a60327333343a836689291b0 Mon Sep 17 00:00:00 2001
From: denzor200 <denismikhaylov38 at gmail.com>
Date: Mon, 29 Dec 2025 21:07:46 +0300
Subject: [PATCH 32/49] refactoring

---
 .../misc/BoolBitwiseOperationCheck.cpp        | 207 ++++++++++--------
 1 file changed, 114 insertions(+), 93 deletions(-)

diff --git a/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.cpp b/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.cpp
index c89a956c184dd..f3292989ecefc 100644
--- a/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.cpp
+++ b/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.cpp
@@ -65,80 +65,6 @@ static bool isBitwiseOperation(StringRef Value) {
                             Value);
 }
 
-/// Checks if a binary operator is a bitwise operation that should be treated
-/// as a boolean operation (i.e., should use logical operators instead).
-///
-/// This function determines whether a bitwise operation (|, &, |=, &=, etc.)
-/// is being used in a boolean context, which typically indicates the case where
-/// logical operators (||, &&) should have been used instead.
-///
-/// \param BinOp The binary operator to check. Must not be null.
-/// \param AC The AST context for type checking and parent traversal.
-/// \param RootAssignsToBoolean An output parameter that tracks whether the
-///        root binary operator in the expression tree assigns to a boolean
-///        type. This is used to propagate the assignment context through
-///        nested binary operations. The value is set to true if any operation
-///        in the chain assigns to boolean, false if both operands are boolean
-///        but no assignment occurs, and remains unset if the operation is not
-///        boolean bitwise.
-///
-/// \returns true if the operation is a bitwise operation used in a boolean
-///          context (both operands are boolean, or it assigns to boolean),
-///          false otherwise.
-static bool isBooleanBitwise(const BinaryOperator *BinOp, ASTContext *AC,
-                             std::optional<bool> &RootAssignsToBoolean) {
-  if (!BinOp)
-    return false;
-
-  if (!isBitwiseOperation(BinOp->getOpcodeStr()))
-    return false;
-
-  // Lambda to check if an expression is boolean type, either directly or
-  // recursively through nested binary operators. This handles cases like
-  // `(a | b) & c` where the LHS is itself a boolean bitwise operation.
-  const auto IsBooleanType = [&AC](const Expr *Expr) -> bool {
-    if (Expr->IgnoreImpCasts()
-            ->getType()
-            .getDesugaredType(*AC)
-            ->isBooleanType())
-      return true;
-    std::optional<bool> DummyFlag = false;
-    return isBooleanBitwise(dyn_cast<BinaryOperator>(
-                                Expr->IgnoreParenImpCasts()),
-                            AC, DummyFlag);
-  };
-
-  const bool IsBooleanLHS = IsBooleanType(BinOp->getLHS());
-  const bool IsBooleanRHS = IsBooleanType(BinOp->getRHS());
-
-  // If both operands are boolean, this is definitely a boolean bitwise
-  // operation. Preserve the existing RootAssignsToBoolean value if set,
-  // otherwise set it to false (no assignment context).
-  if (IsBooleanLHS && IsBooleanRHS) {
-    RootAssignsToBoolean = RootAssignsToBoolean.value_or(false);
-    return true;
-  }
-
-  // Check if this operation assigns to a boolean type. This includes:
-  // 1. Operations where at least one operand is boolean and the result is
-  //    assigned to boolean (e.g., `bool x = a | b` where a is int and b is boolean)
-  // 2. Compound assignments where the LHS is boolean (e.g., `x |= y` where y is int and x is boolean)
-  const bool IsRelevantAssignmentToBoolean = 
-    ((IsBooleanLHS || IsBooleanRHS) && assignsToBoolean(BinOp, AC)) ||
-    (BinOp->isCompoundAssignmentOp() && IsBooleanLHS);
-
-  // If this operation assigns to boolean, or if we've already determined that
-  // the root assigns to boolean (from a nested operation), then this is a
-  // boolean bitwise operation. Set RootAssignsToBoolean to true to propagate
-  // this information up the call stack.
-  if (IsRelevantAssignmentToBoolean || RootAssignsToBoolean.value_or(false)) {
-    RootAssignsToBoolean = RootAssignsToBoolean.value_or(true);
-    return true;
-  }
-
-  return false;
-}
-
 static const Expr *getAcceptableCompoundsLHS(const BinaryOperator *BinOp) {
   assert(BinOp->isCompoundAssignmentOp());
   const Expr *LHS = BinOp->getLHS()->IgnoreImpCasts();
@@ -298,34 +224,131 @@ class BinaryOperatorVisitor : public clang::DynamicRecursiveASTVisitor {
   clang::tidy::misc::BoolBitwiseOperationCheck &Check;
   const clang::SourceManager &SM;
   clang::ASTContext &Ctx;
-  std::optional<bool> &RootAssignsToBoolean;
+  /// Three-state boolean to track whether the root binary operator in the
+  /// expression tree assigns to a boolean type and one of operands is boolean.
+  /// This is used to propagate the assignment context through nested binary
+  /// operations.
+  std::optional<bool> RootAssignsToBoolean;
   // Stack to track parent binary operators during traversal
   std::vector<const clang::BinaryOperator *> ParentStack;
 
+  void setRootAssignsToBoolean(bool Value, bool IsRoot) {
+    if (!IsRoot)
+      return;
+    RootAssignsToBoolean = RootAssignsToBoolean.value_or(Value);
+  }
+
+  /// Checks if an expression is boolean type, either directly or recursively
+  /// through nested binary operators. This handles cases like `(a | b) & c`
+  /// where the LHS is itself a boolean bitwise operation.
+  ///
+  /// \param Expr The expression to check.
+  /// \returns true if the expression is boolean type or is a boolean bitwise
+  ///          operation, false otherwise.
+  bool isBooleanType(const clang::Expr *Expr) {
+    if (Expr->IgnoreImpCasts()
+            ->getType()
+            .getDesugaredType(Ctx)
+            ->isBooleanType())
+      return true;
+    return isBooleanBitwise(
+        dyn_cast<clang::BinaryOperator>(Expr->IgnoreParenImpCasts()),
+        /*IsRoot=*/false);
+  }
+
+  /// Checks if a binary operator is a bitwise operation that should be treated
+  /// as a boolean operation (i.e., should use logical operators instead).
+  ///
+  /// This function determines whether a bitwise operation (|, &, |=, &=, etc.)
+  /// is being used in a boolean context, which typically indicates the case
+  /// where logical operators (||, &&) should have been used instead.
+  ///
+  /// \param BinOp The binary operator to check. Must not be null.
+  /// \param RootAssignsToBoolean An output parameter that
+  ///
+  /// \returns true if the operation is a bitwise operation used in a boolean
+  ///          context (both operands are boolean, or it assigns to boolean),
+  ///          false otherwise.
+  bool isBooleanBitwise(const clang::BinaryOperator *BinOp,
+                        bool IsRoot = true) {
+    if (!BinOp)
+      return false;
+
+    if (!isBitwiseOperation(BinOp->getOpcodeStr()))
+      return false;
+
+    assert(!IsRoot || RootAssignsToBoolean == std::nullopt);
+
+    // If we've already determined that the root assigns to boolean (from a
+    // nested operation), then this is a boolean bitwise operation.
+    if (RootAssignsToBoolean.value_or(false))
+      return true;
+
+    const bool IsBooleanLHS = isBooleanType(BinOp->getLHS());
+    const bool IsBooleanRHS = isBooleanType(BinOp->getRHS());
+
+    // If both operands are boolean, this is definitely a boolean bitwise
+    // operation. Preserve the existing RootAssignsToBoolean value if set,
+    // otherwise set it to false (no assignment context).
+    if (IsBooleanLHS && IsBooleanRHS) {
+      setRootAssignsToBoolean(false, IsRoot);
+      return true;
+    }
+
+    // Check if this operation assigns to a boolean type. This includes:
+    // 1. Operations where at least one operand is boolean and the result is
+    //    assigned to boolean (e.g., `bool x = a | b` where a is int and b is
+    //    boolean)
+    // 2. Compound assignments where the LHS is boolean (e.g., `x |= y` where y
+    // is int and x is boolean)
+    const bool IsRelevantAssignmentToBoolean =
+        ((IsBooleanLHS || IsBooleanRHS) && assignsToBoolean(BinOp, &Ctx)) ||
+        (IsBooleanLHS && BinOp->isCompoundAssignmentOp());
+
+    // If this operation assigns to boolean, then this is a boolean bitwise
+    // operation. Set RootAssignsToBoolean to true to propagate this information
+    // up the call stack.
+    if (IsRelevantAssignmentToBoolean) {
+      setRootAssignsToBoolean(true, IsRoot);
+      return true;
+    }
+
+    return false;
+  }
+
+  /// Checks if BinOp is a direct child of the parent binary operator in the
+  /// stack (ignoring parentheses and implicit casts).
+  bool isDirectChildOfParent(const clang::BinaryOperator *BinOp) const {
+    if (ParentStack.empty())
+      return true;
+
+    const clang::BinaryOperator *Parent = ParentStack.back();
+    const std::array<const Expr *, 2> ParentOperands = {
+        Parent->getLHS(), Parent->getRHS()};
+
+    return llvm::any_of(ParentOperands, [&](const Expr *E) {
+      return E->IgnoreParenImpCasts() == BinOp;
+    });
+  }
+
 public:
   BinaryOperatorVisitor(clang::tidy::misc::BoolBitwiseOperationCheck &Check,
-                        const clang::SourceManager &SM,
-                        clang::ASTContext &Ctx,
-                        std::optional<bool> &RootAssignsToBoolean)
-      : Check(Check), SM(SM), Ctx(Ctx),
-        RootAssignsToBoolean(RootAssignsToBoolean) {}
+                        const clang::SourceManager &SM, clang::ASTContext &Ctx)
+      : Check(Check), SM(SM), Ctx(Ctx) {}
 
   bool TraverseBinaryOperator(clang::BinaryOperator *BinOp) override {
     if (!BinOp)
       return true;
 
-    // Check if this BinOp is a direct child of the parent in the stack.
-    // If not, we skip processing it (don't add to stack).
-    if (!ParentStack.empty() && !(ParentStack.back()->getLHS()->IgnoreParenImpCasts() == BinOp || ParentStack.back()->getRHS()->IgnoreParenImpCasts() == BinOp)) {
+    if (!isDirectChildOfParent(BinOp))
       return true;
-    }
 
-    // Push current binary operator as parent for children
+    // Track this binary operator as a parent for its children.
     ParentStack.push_back(BinOp);
-    // Traverse children
-    bool Result = clang::DynamicRecursiveASTVisitor::TraverseBinaryOperator(BinOp);
-    // Pop after traversal
+    const bool Result =
+        clang::DynamicRecursiveASTVisitor::TraverseBinaryOperator(BinOp);
     ParentStack.pop_back();
+
     return Result;
   }
 
@@ -336,7 +359,7 @@ class BinaryOperatorVisitor : public clang::DynamicRecursiveASTVisitor {
     const clang::BinaryOperator *ParentBinOp =
         ParentStack.size() < 2 ? nullptr : ParentStack[ParentStack.size() - 2];
 
-    if (isBooleanBitwise(BinOp, &Ctx, RootAssignsToBoolean)) {
+    if (isBooleanBitwise(BinOp)) {
       assert(RootAssignsToBoolean.has_value());
       Check.emitWarningAndChangeOperatorsIfPossible(BinOp, ParentBinOp, SM,
                                                     Ctx);
@@ -349,14 +372,12 @@ class BinaryOperatorVisitor : public clang::DynamicRecursiveASTVisitor {
 
 void BoolBitwiseOperationCheck::check(const MatchFinder::MatchResult &Result) {
   const auto *BinOpRoot = Result.Nodes.getNodeAs<BinaryOperator>("binOpRoot");
-  if (!BinOpRoot)
-    return;
+  assert(BinOpRoot);
 
   const SourceManager &SM = *Result.SourceManager;
   ASTContext &Ctx = *Result.Context;
-  std::optional<bool> RootAssignsToBoolean = std::nullopt;
 
-  BinaryOperatorVisitor Visitor(*this, SM, Ctx, RootAssignsToBoolean);
+  BinaryOperatorVisitor Visitor(*this, SM, Ctx);
   // TraverseStmt requires non-const pointer, but we're only reading
   Visitor.TraverseStmt(const_cast<BinaryOperator *>(BinOpRoot));
 }

>From de69f76bf7f8044fe0c65bb960ca7c973a28dbc1 Mon Sep 17 00:00:00 2001
From: denzor200 <denismikhaylov38 at gmail.com>
Date: Wed, 31 Dec 2025 00:11:08 +0300
Subject: [PATCH 33/49] get rid of RootAssignsToBoolean

---
 .../misc/BoolBitwiseOperationCheck.cpp        | 92 +++++++------------
 ...itwise-operation-not-only-bool-operand.cpp |  7 +-
 2 files changed, 38 insertions(+), 61 deletions(-)

diff --git a/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.cpp b/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.cpp
index f3292989ecefc..6ddd2e3f87fad 100644
--- a/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.cpp
+++ b/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.cpp
@@ -224,20 +224,9 @@ class BinaryOperatorVisitor : public clang::DynamicRecursiveASTVisitor {
   clang::tidy::misc::BoolBitwiseOperationCheck &Check;
   const clang::SourceManager &SM;
   clang::ASTContext &Ctx;
-  /// Three-state boolean to track whether the root binary operator in the
-  /// expression tree assigns to a boolean type and one of operands is boolean.
-  /// This is used to propagate the assignment context through nested binary
-  /// operations.
-  std::optional<bool> RootAssignsToBoolean;
   // Stack to track parent binary operators during traversal
   std::vector<const clang::BinaryOperator *> ParentStack;
 
-  void setRootAssignsToBoolean(bool Value, bool IsRoot) {
-    if (!IsRoot)
-      return;
-    RootAssignsToBoolean = RootAssignsToBoolean.value_or(Value);
-  }
-
   /// Checks if an expression is boolean type, either directly or recursively
   /// through nested binary operators. This handles cases like `(a | b) & c`
   /// where the LHS is itself a boolean bitwise operation.
@@ -256,6 +245,26 @@ class BinaryOperatorVisitor : public clang::DynamicRecursiveASTVisitor {
         /*IsRoot=*/false);
   }
 
+  /// Checks if BinOp is a direct child of the parent binary operator in the
+  /// stack (ignoring parentheses and implicit casts).
+  bool isDirectChildOfParent(const clang::BinaryOperator *BinOp) const {
+    if (ParentStack.empty())
+      return true;
+
+    const clang::BinaryOperator *Parent = ParentStack.back();
+    const std::array<const Expr *, 2> ParentOperands = {
+        Parent->getLHS(), Parent->getRHS()};
+
+    return llvm::any_of(ParentOperands, [&](const Expr *E) {
+      return E->IgnoreParenImpCasts() == BinOp;
+    });
+  }
+
+public:
+  BinaryOperatorVisitor(clang::tidy::misc::BoolBitwiseOperationCheck &Check,
+                        const clang::SourceManager &SM, clang::ASTContext &Ctx)
+      : Check(Check), SM(SM), Ctx(Ctx) {}
+
   /// Checks if a binary operator is a bitwise operation that should be treated
   /// as a boolean operation (i.e., should use logical operators instead).
   ///
@@ -264,7 +273,6 @@ class BinaryOperatorVisitor : public clang::DynamicRecursiveASTVisitor {
   /// where logical operators (||, &&) should have been used instead.
   ///
   /// \param BinOp The binary operator to check. Must not be null.
-  /// \param RootAssignsToBoolean An output parameter that
   ///
   /// \returns true if the operation is a bitwise operation used in a boolean
   ///          context (both operands are boolean, or it assigns to boolean),
@@ -274,27 +282,9 @@ class BinaryOperatorVisitor : public clang::DynamicRecursiveASTVisitor {
     if (!BinOp)
       return false;
 
-    if (!isBitwiseOperation(BinOp->getOpcodeStr()))
-      return false;
-
-    assert(!IsRoot || RootAssignsToBoolean == std::nullopt);
-
-    // If we've already determined that the root assigns to boolean (from a
-    // nested operation), then this is a boolean bitwise operation.
-    if (RootAssignsToBoolean.value_or(false))
-      return true;
-
     const bool IsBooleanLHS = isBooleanType(BinOp->getLHS());
     const bool IsBooleanRHS = isBooleanType(BinOp->getRHS());
 
-    // If both operands are boolean, this is definitely a boolean bitwise
-    // operation. Preserve the existing RootAssignsToBoolean value if set,
-    // otherwise set it to false (no assignment context).
-    if (IsBooleanLHS && IsBooleanRHS) {
-      setRootAssignsToBoolean(false, IsRoot);
-      return true;
-    }
-
     // Check if this operation assigns to a boolean type. This includes:
     // 1. Operations where at least one operand is boolean and the result is
     //    assigned to boolean (e.g., `bool x = a | b` where a is int and b is
@@ -309,33 +299,15 @@ class BinaryOperatorVisitor : public clang::DynamicRecursiveASTVisitor {
     // operation. Set RootAssignsToBoolean to true to propagate this information
     // up the call stack.
     if (IsRelevantAssignmentToBoolean) {
-      setRootAssignsToBoolean(true, IsRoot);
       return true;
     }
 
-    return false;
-  }
-
-  /// Checks if BinOp is a direct child of the parent binary operator in the
-  /// stack (ignoring parentheses and implicit casts).
-  bool isDirectChildOfParent(const clang::BinaryOperator *BinOp) const {
-    if (ParentStack.empty())
-      return true;
-
-    const clang::BinaryOperator *Parent = ParentStack.back();
-    const std::array<const Expr *, 2> ParentOperands = {
-        Parent->getLHS(), Parent->getRHS()};
-
-    return llvm::any_of(ParentOperands, [&](const Expr *E) {
-      return E->IgnoreParenImpCasts() == BinOp;
-    });
+    // If both operands are boolean, this is definitely a boolean bitwise
+    // operation. Preserve the existing RootAssignsToBoolean value if set,
+    // otherwise set it to false (no assignment context).
+    return (IsBooleanLHS && IsBooleanRHS);
   }
 
-public:
-  BinaryOperatorVisitor(clang::tidy::misc::BoolBitwiseOperationCheck &Check,
-                        const clang::SourceManager &SM, clang::ASTContext &Ctx)
-      : Check(Check), SM(SM), Ctx(Ctx) {}
-
   bool TraverseBinaryOperator(clang::BinaryOperator *BinOp) override {
     if (!BinOp)
       return true;
@@ -356,14 +328,14 @@ class BinaryOperatorVisitor : public clang::DynamicRecursiveASTVisitor {
     if (!BinOp)
       return true;
 
+    if (!isBitwiseOperation(BinOp->getOpcodeStr()))
+      return true;
+
     const clang::BinaryOperator *ParentBinOp =
         ParentStack.size() < 2 ? nullptr : ParentStack[ParentStack.size() - 2];
 
-    if (isBooleanBitwise(BinOp)) {
-      assert(RootAssignsToBoolean.has_value());
-      Check.emitWarningAndChangeOperatorsIfPossible(BinOp, ParentBinOp, SM,
-                                                    Ctx);
-    }
+    Check.emitWarningAndChangeOperatorsIfPossible(BinOp, ParentBinOp, SM,
+                                                  Ctx);
 
     return true;
   }
@@ -378,8 +350,10 @@ void BoolBitwiseOperationCheck::check(const MatchFinder::MatchResult &Result) {
   ASTContext &Ctx = *Result.Context;
 
   BinaryOperatorVisitor Visitor(*this, SM, Ctx);
-  // TraverseStmt requires non-const pointer, but we're only reading
-  Visitor.TraverseStmt(const_cast<BinaryOperator *>(BinOpRoot));
+  if (Visitor.isBooleanBitwise(BinOpRoot)) {
+    // TraverseStmt requires non-const pointer, but we're only reading
+    Visitor.TraverseStmt(const_cast<BinaryOperator *>(BinOpRoot));
+  }
 }
 
 } // namespace clang::tidy::misc
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 f93297a42f686..c3b6744c1cb14 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
@@ -2,15 +2,18 @@
 
 // The case is taken from the real code in clang/lib/APINotes/APINotesWriter.cpp
 
+void take(bool value) {}
+void take_int(int value) {}
+
 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;
+    take_int((flags << 1) | value);
+    take_int((flags << 1) | (flags << 2) | value);
 }
 
-void take(bool value) {}
-
 // FIXME: implement `template<bool bb=true|1>` cases
 
 void assign_to_boolean(unsigned flags, bool value) {

>From dee0b3681832c0924def7ef1b8f4a867b666b3b8 Mon Sep 17 00:00:00 2001
From: denzor200 <denismikhaylov38 at gmail.com>
Date: Mon, 5 Jan 2026 00:52:38 +0300
Subject: [PATCH 34/49] narrow the matching

---
 .../misc/BoolBitwiseOperationCheck.cpp        | 26 +++++++++++--------
 1 file changed, 15 insertions(+), 11 deletions(-)

diff --git a/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.cpp b/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.cpp
index 6ddd2e3f87fad..663031be9c1a0 100644
--- a/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.cpp
+++ b/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.cpp
@@ -85,9 +85,10 @@ void BoolBitwiseOperationCheck::storeOptions(
 
 void BoolBitwiseOperationCheck::registerMatchers(MatchFinder *Finder) {
   Finder->addMatcher(
-      binaryOperator(unless(isExpansionInSystemHeader()),
-                     unless(hasParent(binaryOperator())) // ignoring parenExpr
-                     )
+      binaryOperator(unless(hasParent(binaryOperator(hasAnyOperatorName(
+                         "|", "&", "|=", "&=")))), // ignoring parenExpr
+                     hasAnyOperatorName("|", "&", "|=", "&="),
+                     optionally(hasParent(binaryOperator().bind("p"))))
           .bind("binOpRoot"),
       this);
 }
@@ -224,6 +225,7 @@ class BinaryOperatorVisitor : public clang::DynamicRecursiveASTVisitor {
   clang::tidy::misc::BoolBitwiseOperationCheck &Check;
   const clang::SourceManager &SM;
   clang::ASTContext &Ctx;
+  const clang::BinaryOperator *const ParentRoot;
   // Stack to track parent binary operators during traversal
   std::vector<const clang::BinaryOperator *> ParentStack;
 
@@ -252,8 +254,8 @@ class BinaryOperatorVisitor : public clang::DynamicRecursiveASTVisitor {
       return true;
 
     const clang::BinaryOperator *Parent = ParentStack.back();
-    const std::array<const Expr *, 2> ParentOperands = {
-        Parent->getLHS(), Parent->getRHS()};
+    const std::array<const Expr *, 2> ParentOperands = {Parent->getLHS(),
+                                                        Parent->getRHS()};
 
     return llvm::any_of(ParentOperands, [&](const Expr *E) {
       return E->IgnoreParenImpCasts() == BinOp;
@@ -262,8 +264,9 @@ class BinaryOperatorVisitor : public clang::DynamicRecursiveASTVisitor {
 
 public:
   BinaryOperatorVisitor(clang::tidy::misc::BoolBitwiseOperationCheck &Check,
-                        const clang::SourceManager &SM, clang::ASTContext &Ctx)
-      : Check(Check), SM(SM), Ctx(Ctx) {}
+                        const clang::SourceManager &SM, clang::ASTContext &Ctx,
+                        const clang::BinaryOperator *ParentRoot)
+      : Check(Check), SM(SM), Ctx(Ctx), ParentRoot(ParentRoot) {}
 
   /// Checks if a binary operator is a bitwise operation that should be treated
   /// as a boolean operation (i.e., should use logical operators instead).
@@ -332,10 +335,10 @@ class BinaryOperatorVisitor : public clang::DynamicRecursiveASTVisitor {
       return true;
 
     const clang::BinaryOperator *ParentBinOp =
-        ParentStack.size() < 2 ? nullptr : ParentStack[ParentStack.size() - 2];
+        ParentStack.size() < 2 ? ParentRoot
+                               : ParentStack[ParentStack.size() - 2];
 
-    Check.emitWarningAndChangeOperatorsIfPossible(BinOp, ParentBinOp, SM,
-                                                  Ctx);
+    Check.emitWarningAndChangeOperatorsIfPossible(BinOp, ParentBinOp, SM, Ctx);
 
     return true;
   }
@@ -344,12 +347,13 @@ class BinaryOperatorVisitor : public clang::DynamicRecursiveASTVisitor {
 
 void BoolBitwiseOperationCheck::check(const MatchFinder::MatchResult &Result) {
   const auto *BinOpRoot = Result.Nodes.getNodeAs<BinaryOperator>("binOpRoot");
+  const auto *ParentRoot = Result.Nodes.getNodeAs<BinaryOperator>("p");
   assert(BinOpRoot);
 
   const SourceManager &SM = *Result.SourceManager;
   ASTContext &Ctx = *Result.Context;
 
-  BinaryOperatorVisitor Visitor(*this, SM, Ctx);
+  BinaryOperatorVisitor Visitor(*this, SM, Ctx, ParentRoot);
   if (Visitor.isBooleanBitwise(BinOpRoot)) {
     // TraverseStmt requires non-const pointer, but we're only reading
     Visitor.TraverseStmt(const_cast<BinaryOperator *>(BinOpRoot));

>From f38960cb7661a6ec230d9fcb6f41216e69c634ca Mon Sep 17 00:00:00 2001
From: denzor200 <denismikhaylov38 at gmail.com>
Date: Mon, 5 Jan 2026 01:16:15 +0300
Subject: [PATCH 35/49] get rid of assignsToBoolean

---
 .../misc/BoolBitwiseOperationCheck.cpp        | 78 ++++++++-----------
 .../misc/BoolBitwiseOperationCheck.h          |  3 -
 2 files changed, 33 insertions(+), 48 deletions(-)

diff --git a/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.cpp b/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.cpp
index 663031be9c1a0..138ec02406124 100644
--- a/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.cpp
+++ b/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.cpp
@@ -19,28 +19,6 @@ using namespace clang::ast_matchers;
 
 namespace clang::tidy::misc {
 
-static const DynTypedNode *ignoreParensTowardsTheRoot(const DynTypedNode *N,
-                                                      ASTContext *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;
-}
-
-static bool assignsToBoolean(const BinaryOperator *BinOp, ASTContext *AC) {
-  const TraversalKindScope RAII(*AC, TK_AsIs);
-  auto Parents = AC->getParents(*BinOp);
-
-  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>
     OperatorsTransformation{{{"|", "||"},
                              {"|=", "||"},
@@ -84,13 +62,16 @@ void BoolBitwiseOperationCheck::storeOptions(
 }
 
 void BoolBitwiseOperationCheck::registerMatchers(MatchFinder *Finder) {
-  Finder->addMatcher(
+  const auto BinOpRoot = traverse(
+      TK_IgnoreUnlessSpelledInSource,
       binaryOperator(unless(hasParent(binaryOperator(hasAnyOperatorName(
                          "|", "&", "|=", "&=")))), // ignoring parenExpr
                      hasAnyOperatorName("|", "&", "|=", "&="),
                      optionally(hasParent(binaryOperator().bind("p"))))
-          .bind("binOpRoot"),
-      this);
+          .bind("binOpRoot"));
+  const auto BooleanICE =
+      implicitCastExpr(hasType(booleanType()), has(BinOpRoot)).bind("ice");
+  Finder->addMatcher(expr(anyOf(BooleanICE, BinOpRoot)), this);
 }
 
 void BoolBitwiseOperationCheck::emitWarningAndChangeOperatorsIfPossible(
@@ -281,34 +262,39 @@ class BinaryOperatorVisitor : public clang::DynamicRecursiveASTVisitor {
   ///          context (both operands are boolean, or it assigns to boolean),
   ///          false otherwise.
   bool isBooleanBitwise(const clang::BinaryOperator *BinOp,
-                        bool IsRoot = true) {
+                        bool AssignsToBoolean, bool IsRoot = true) {
     if (!BinOp)
       return false;
 
     const bool IsBooleanLHS = isBooleanType(BinOp->getLHS());
     const bool IsBooleanRHS = isBooleanType(BinOp->getRHS());
 
-    // Check if this operation assigns to a boolean type. This includes:
-    // 1. Operations where at least one operand is boolean and the result is
-    //    assigned to boolean (e.g., `bool x = a | b` where a is int and b is
-    //    boolean)
-    // 2. Compound assignments where the LHS is boolean (e.g., `x |= y` where y
-    // is int and x is boolean)
-    const bool IsRelevantAssignmentToBoolean =
-        ((IsBooleanLHS || IsBooleanRHS) && assignsToBoolean(BinOp, &Ctx)) ||
-        (IsBooleanLHS && BinOp->isCompoundAssignmentOp());
-
-    // If this operation assigns to boolean, then this is a boolean bitwise
-    // operation. Set RootAssignsToBoolean to true to propagate this information
-    // up the call stack.
-    if (IsRelevantAssignmentToBoolean) {
-      return true;
-    }
-
     // If both operands are boolean, this is definitely a boolean bitwise
     // operation. Preserve the existing RootAssignsToBoolean value if set,
     // otherwise set it to false (no assignment context).
-    return (IsBooleanLHS && IsBooleanRHS);
+    if (IsBooleanLHS && IsBooleanRHS)
+      return true;
+
+    if (IsRoot) {
+      // Check if this operation assigns to a boolean type. This includes:
+      // 1. Operations where at least one operand is boolean and the result is
+      //    assigned to boolean (e.g., `bool x = a | b` where a is int and b is
+      //    boolean)
+      // 2. Compound assignments where the LHS is boolean (e.g., `x |= y` where
+      // y is int and x is boolean)
+      const bool IsRelevantAssignmentToBoolean =
+          ((IsBooleanLHS || IsBooleanRHS) && AssignsToBoolean) ||
+          (IsBooleanLHS && BinOp->isCompoundAssignmentOp());
+
+      // If this operation assigns to boolean, then this is a boolean bitwise
+      // operation. Set RootAssignsToBoolean to true to propagate this
+      // information up the call stack.
+      if (IsRelevantAssignmentToBoolean) {
+        return true;
+      }
+    }
+
+    return false;
   }
 
   bool TraverseBinaryOperator(clang::BinaryOperator *BinOp) override {
@@ -348,13 +334,15 @@ class BinaryOperatorVisitor : public clang::DynamicRecursiveASTVisitor {
 void BoolBitwiseOperationCheck::check(const MatchFinder::MatchResult &Result) {
   const auto *BinOpRoot = Result.Nodes.getNodeAs<BinaryOperator>("binOpRoot");
   const auto *ParentRoot = Result.Nodes.getNodeAs<BinaryOperator>("p");
+  const bool AssignsToBoolean =
+      Result.Nodes.getMap().find("ice") != Result.Nodes.getMap().end();
   assert(BinOpRoot);
 
   const SourceManager &SM = *Result.SourceManager;
   ASTContext &Ctx = *Result.Context;
 
   BinaryOperatorVisitor Visitor(*this, SM, Ctx, ParentRoot);
-  if (Visitor.isBooleanBitwise(BinOpRoot)) {
+  if (Visitor.isBooleanBitwise(BinOpRoot, AssignsToBoolean)) {
     // TraverseStmt requires non-const pointer, but we're only reading
     Visitor.TraverseStmt(const_cast<BinaryOperator *>(BinOpRoot));
   }
diff --git a/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.h b/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.h
index 4a3b36a12302b..b3977a3d41824 100644
--- a/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.h
+++ b/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.h
@@ -28,9 +28,6 @@ class BoolBitwiseOperationCheck : public ClangTidyCheck {
   bool isLanguageVersionSupported(const LangOptions &LangOpts) const override {
     return LangOpts.CPlusPlus || LangOpts.C99;
   }
-  std::optional<TraversalKind> getCheckTraversalKind() const override {
-    return TK_IgnoreUnlessSpelledInSource;
-  }
 
   void emitWarningAndChangeOperatorsIfPossible(
       const BinaryOperator *BinOp, const BinaryOperator *ParentBinOp,

>From 0d74db41a6fd3f820f9751d509b9a0925dfdbec8 Mon Sep 17 00:00:00 2001
From: denzor200 <denismikhaylov38 at gmail.com>
Date: Fri, 16 Jan 2026 18:06:45 +0300
Subject: [PATCH 36/49] Fix for  false positive

---
 .../clang-tidy/misc/BoolBitwiseOperationCheck.cpp        | 3 +++
 .../misc/bool-bitwise-operation-nontraditional.cpp       | 9 +++++++++
 .../clang-tidy/checkers/misc/bool-bitwise-operation.cpp  | 9 +++++++++
 3 files changed, 21 insertions(+)

diff --git a/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.cpp b/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.cpp
index 138ec02406124..a81950204700a 100644
--- a/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.cpp
+++ b/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.cpp
@@ -266,6 +266,9 @@ class BinaryOperatorVisitor : public clang::DynamicRecursiveASTVisitor {
     if (!BinOp)
       return false;
 
+    if (!isBitwiseOperation(BinOp->getOpcodeStr()))
+      return false;
+
     const bool IsBooleanLHS = isBooleanType(BinOp->getLHS());
     const bool IsBooleanRHS = isBooleanType(BinOp->getRHS());
 
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 c6a8a7810c93b..4a0581b6f194a 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
@@ -409,3 +409,12 @@ int bad_in_template_lambda_captured(T a, T b) {
 }
 
 int dummy = bad_in_template(true, false) + bad_in_template_lambda_captured(false, true);
+
+void test_bug_isBooleanBitwise_recursive_classification() {
+    bool a = true, b = false, c = true;
+    int i = 0;
+
+    bool result1 = (a + b) bitor i;
+
+    bool result2 = (a * b + c) bitor i;
+}
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 6487026b07583..2c30de717d41e 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
@@ -407,3 +407,12 @@ int bad_in_template_lambda_captured(T a, T b) {
 }
 
 int dummy = bad_in_template(true, false) + bad_in_template_lambda_captured(false, true);
+
+void test_bug_isBooleanBitwise_recursive_classification() {
+    bool a = true, b = false, c = true;
+    int i = 0;
+
+    bool result1 = (a + b) | i;
+
+    bool result2 = (a * b + c) | i;
+}

>From 09937d819bb1c047f410fb7c2d740316d889bcb5 Mon Sep 17 00:00:00 2001
From: denzor200 <denismikhaylov38 at gmail.com>
Date: Fri, 16 Jan 2026 19:32:47 +0300
Subject: [PATCH 37/49] refactoring

---
 .../misc/BoolBitwiseOperationCheck.cpp        | 91 ++++++++++---------
 1 file changed, 50 insertions(+), 41 deletions(-)

diff --git a/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.cpp b/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.cpp
index a81950204700a..efacbace7ccf1 100644
--- a/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.cpp
+++ b/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.cpp
@@ -49,6 +49,33 @@ static const Expr *getAcceptableCompoundsLHS(const BinaryOperator *BinOp) {
   return isa<DeclRefExpr, MemberExpr>(LHS) ? LHS : nullptr;
 }
 
+/// Checks if all leaf nodes in an expression satisfy a given condition. This
+/// handles cases like `(a | b) & c` where we need to check that a, b, and c
+/// all satisfy the condition.
+///
+/// \param Expr The expression to check.
+/// \param Condition A function that checks if an expression satisfies the
+///                  desired condition.
+/// \returns true if all leaf nodes satisfy the condition, false otherwise.
+template <typename F>
+static bool allLeavesSatisfy(const clang::Expr *Expr, const F& Condition) {
+  // For leaf nodes, check if the condition is satisfied
+  if (Condition(Expr))
+    return true;
+
+  Expr = Expr->IgnoreParenImpCasts();
+
+  // If it's a binary operator, recursively check both operands
+  if (const auto *BinOp = dyn_cast<clang::BinaryOperator>(Expr)) {
+    if (!isBitwiseOperation(BinOp->getOpcodeStr()))
+      return false;
+    return allLeavesSatisfy(BinOp->getLHS(), Condition) &&
+            allLeavesSatisfy(BinOp->getRHS(), Condition);
+  }
+
+  return false;
+}
+
 BoolBitwiseOperationCheck::BoolBitwiseOperationCheck(StringRef Name,
                                                      ClangTidyContext *Context)
     : ClangTidyCheck(Name, Context),
@@ -210,24 +237,6 @@ class BinaryOperatorVisitor : public clang::DynamicRecursiveASTVisitor {
   // Stack to track parent binary operators during traversal
   std::vector<const clang::BinaryOperator *> ParentStack;
 
-  /// Checks if an expression is boolean type, either directly or recursively
-  /// through nested binary operators. This handles cases like `(a | b) & c`
-  /// where the LHS is itself a boolean bitwise operation.
-  ///
-  /// \param Expr The expression to check.
-  /// \returns true if the expression is boolean type or is a boolean bitwise
-  ///          operation, false otherwise.
-  bool isBooleanType(const clang::Expr *Expr) {
-    if (Expr->IgnoreImpCasts()
-            ->getType()
-            .getDesugaredType(Ctx)
-            ->isBooleanType())
-      return true;
-    return isBooleanBitwise(
-        dyn_cast<clang::BinaryOperator>(Expr->IgnoreParenImpCasts()),
-        /*IsRoot=*/false);
-  }
-
   /// Checks if BinOp is a direct child of the parent binary operator in the
   /// stack (ignoring parentheses and implicit casts).
   bool isDirectChildOfParent(const clang::BinaryOperator *BinOp) const {
@@ -262,15 +271,21 @@ class BinaryOperatorVisitor : public clang::DynamicRecursiveASTVisitor {
   ///          context (both operands are boolean, or it assigns to boolean),
   ///          false otherwise.
   bool isBooleanBitwise(const clang::BinaryOperator *BinOp,
-                        bool AssignsToBoolean, bool IsRoot = true) {
+                        bool AssignsToBoolean) {
     if (!BinOp)
       return false;
 
     if (!isBitwiseOperation(BinOp->getOpcodeStr()))
       return false;
 
-    const bool IsBooleanLHS = isBooleanType(BinOp->getLHS());
-    const bool IsBooleanRHS = isBooleanType(BinOp->getRHS());
+    auto IsBooleanType = [&](const clang::Expr *E) {
+      return E->IgnoreImpCasts()
+          ->getType()
+          .getDesugaredType(Ctx)
+          ->isBooleanType();
+    };
+    const bool IsBooleanLHS = allLeavesSatisfy(BinOp->getLHS(), IsBooleanType);
+    const bool IsBooleanRHS = allLeavesSatisfy(BinOp->getRHS(), IsBooleanType);
 
     // If both operands are boolean, this is definitely a boolean bitwise
     // operation. Preserve the existing RootAssignsToBoolean value if set,
@@ -278,26 +293,20 @@ class BinaryOperatorVisitor : public clang::DynamicRecursiveASTVisitor {
     if (IsBooleanLHS && IsBooleanRHS)
       return true;
 
-    if (IsRoot) {
-      // Check if this operation assigns to a boolean type. This includes:
-      // 1. Operations where at least one operand is boolean and the result is
-      //    assigned to boolean (e.g., `bool x = a | b` where a is int and b is
-      //    boolean)
-      // 2. Compound assignments where the LHS is boolean (e.g., `x |= y` where
-      // y is int and x is boolean)
-      const bool IsRelevantAssignmentToBoolean =
-          ((IsBooleanLHS || IsBooleanRHS) && AssignsToBoolean) ||
-          (IsBooleanLHS && BinOp->isCompoundAssignmentOp());
-
-      // If this operation assigns to boolean, then this is a boolean bitwise
-      // operation. Set RootAssignsToBoolean to true to propagate this
-      // information up the call stack.
-      if (IsRelevantAssignmentToBoolean) {
-        return true;
-      }
-    }
-
-    return false;
+    // Check if this operation assigns to a boolean type. This includes:
+    // 1. Operations where at least one operand is boolean and the result is
+    //    assigned to boolean (e.g., `bool x = a | b` where a is int and b is
+    //    boolean)
+    // 2. Compound assignments where the LHS is boolean (e.g., `x |= y` where
+    // y is int and x is boolean)
+    const bool IsRelevantAssignmentToBoolean =
+        ((IsBooleanLHS || IsBooleanRHS) && AssignsToBoolean) ||
+        (IsBooleanLHS && BinOp->isCompoundAssignmentOp());
+
+    // If this operation assigns to boolean, then this is a boolean bitwise
+    // operation. Set RootAssignsToBoolean to true to propagate this
+    // information up the call stack.
+    return IsRelevantAssignmentToBoolean;
   }
 
   bool TraverseBinaryOperator(clang::BinaryOperator *BinOp) override {

>From 32ee87266db9e540880bca9e180d3917a5fe75ce Mon Sep 17 00:00:00 2001
From: denzor200 <denismikhaylov38 at gmail.com>
Date: Fri, 16 Jan 2026 20:19:14 +0300
Subject: [PATCH 38/49] get ride of isBooleanBitwise function

---
 .../misc/BoolBitwiseOperationCheck.cpp        | 127 ++++++++----------
 1 file changed, 56 insertions(+), 71 deletions(-)

diff --git a/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.cpp b/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.cpp
index efacbace7ccf1..bc69853f271b2 100644
--- a/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.cpp
+++ b/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.cpp
@@ -49,16 +49,16 @@ static const Expr *getAcceptableCompoundsLHS(const BinaryOperator *BinOp) {
   return isa<DeclRefExpr, MemberExpr>(LHS) ? LHS : nullptr;
 }
 
-/// Checks if all leaf nodes in an expression satisfy a given condition. This
+/// Checks if all leaf nodes in an bitwise expression satisfy a given condition. This
 /// handles cases like `(a | b) & c` where we need to check that a, b, and c
 /// all satisfy the condition.
 ///
-/// \param Expr The expression to check.
-/// \param Condition A function that checks if an expression satisfies the
+/// \param Expr The bitwise expression to check.
+/// \param Condition A function that checks if an leaf node satisfies the
 ///                  desired condition.
 /// \returns true if all leaf nodes satisfy the condition, false otherwise.
 template <typename F>
-static bool allLeavesSatisfy(const clang::Expr *Expr, const F& Condition) {
+static bool allLeavesOfBitwiseSatisfy(const clang::Expr *Expr, const F& Condition) {
   // For leaf nodes, check if the condition is satisfied
   if (Condition(Expr))
     return true;
@@ -69,13 +69,26 @@ static bool allLeavesSatisfy(const clang::Expr *Expr, const F& Condition) {
   if (const auto *BinOp = dyn_cast<clang::BinaryOperator>(Expr)) {
     if (!isBitwiseOperation(BinOp->getOpcodeStr()))
       return false;
-    return allLeavesSatisfy(BinOp->getLHS(), Condition) &&
-            allLeavesSatisfy(BinOp->getRHS(), Condition);
+    return allLeavesOfBitwiseSatisfy(BinOp->getLHS(), Condition) &&
+            allLeavesOfBitwiseSatisfy(BinOp->getRHS(), Condition);
   }
 
   return false;
 }
 
+/// Custom matcher that checks if all leaf nodes in an bitwise expression satisfy
+/// the given inner matcher condition. This uses allLeavesOfBitwiseSatisfy to recursively
+///
+/// Example usage:
+///   expr(hasAllLeavesOfBitwiseSatisfying(hasType(booleanType())))
+AST_MATCHER_P(Expr, hasAllLeavesOfBitwiseSatisfying,
+              ast_matchers::internal::Matcher<Expr>, InnerMatcher) {
+  auto Condition = [&](const clang::Expr *E) -> bool {
+    return InnerMatcher.matches(*E, Finder, Builder);
+  };
+  return allLeavesOfBitwiseSatisfy(&Node, Condition);
+}
+
 BoolBitwiseOperationCheck::BoolBitwiseOperationCheck(StringRef Name,
                                                      ClangTidyContext *Context)
     : ClangTidyCheck(Name, Context),
@@ -89,16 +102,43 @@ void BoolBitwiseOperationCheck::storeOptions(
 }
 
 void BoolBitwiseOperationCheck::registerMatchers(MatchFinder *Finder) {
-  const auto BinOpRoot = traverse(
+  // Matcher for checking if all leaves in an expression are boolean type
+  auto BooleanLeaves = hasAllLeavesOfBitwiseSatisfying(hasType(booleanType()));
+
+  auto BitwiseOps = hasAnyOperatorName("|", "&", "|=", "&=");
+  auto CompoundBitwiseOps = hasAnyOperatorName("|=", "&=");
+  auto NotNestedInBitwise = unless(hasParent(binaryOperator(BitwiseOps)));
+  auto OptionalParent = optionally(hasParent(binaryOperator().bind("p")));
+
+  // Conditions that make it a boolean bitwise operation without ICE context:
+  // 1. Both LHS and RHS have all boolean leaves
+  // 2. LHS has boolean leaves AND it's a compound assignment
+  auto BothBoolean = allOf(hasLHS(BooleanLeaves), hasRHS(BooleanLeaves));
+  auto CompoundWithBoolLHS = allOf(hasLHS(BooleanLeaves), CompoundBitwiseOps);
+  auto NoContextNeeded = anyOf(BothBoolean, CompoundWithBoolLHS);
+
+  // At least one boolean operand (needs ICE context to be considered boolean
+  // bitwise)
+  auto AtLeastOneBoolean = anyOf(hasLHS(BooleanLeaves), hasRHS(BooleanLeaves));
+
+  // Matcher for binop that doesn't need ICE context
+  auto BinOpNoContext = traverse(
+      TK_IgnoreUnlessSpelledInSource,
+      binaryOperator(NotNestedInBitwise, BitwiseOps, OptionalParent,
+                     NoContextNeeded)
+          .bind("binOpRoot"));
+
+  // Matcher for binop that needs ICE context (at least one boolean operand,
+  // but not already covered by NoContextNeeded)
+  auto BinOpNeedsContext = traverse(
       TK_IgnoreUnlessSpelledInSource,
-      binaryOperator(unless(hasParent(binaryOperator(hasAnyOperatorName(
-                         "|", "&", "|=", "&=")))), // ignoring parenExpr
-                     hasAnyOperatorName("|", "&", "|=", "&="),
-                     optionally(hasParent(binaryOperator().bind("p"))))
+      binaryOperator(NotNestedInBitwise, BitwiseOps, OptionalParent,
+                     AtLeastOneBoolean, unless(NoContextNeeded))
           .bind("binOpRoot"));
-  const auto BooleanICE =
-      implicitCastExpr(hasType(booleanType()), has(BinOpRoot)).bind("ice");
-  Finder->addMatcher(expr(anyOf(BooleanICE, BinOpRoot)), this);
+  auto BooleanICE =
+      implicitCastExpr(hasType(booleanType()), has(BinOpNeedsContext));
+
+  Finder->addMatcher(expr(anyOf(BooleanICE, BinOpNoContext)), this);
 }
 
 void BoolBitwiseOperationCheck::emitWarningAndChangeOperatorsIfPossible(
@@ -258,57 +298,6 @@ class BinaryOperatorVisitor : public clang::DynamicRecursiveASTVisitor {
                         const clang::BinaryOperator *ParentRoot)
       : Check(Check), SM(SM), Ctx(Ctx), ParentRoot(ParentRoot) {}
 
-  /// Checks if a binary operator is a bitwise operation that should be treated
-  /// as a boolean operation (i.e., should use logical operators instead).
-  ///
-  /// This function determines whether a bitwise operation (|, &, |=, &=, etc.)
-  /// is being used in a boolean context, which typically indicates the case
-  /// where logical operators (||, &&) should have been used instead.
-  ///
-  /// \param BinOp The binary operator to check. Must not be null.
-  ///
-  /// \returns true if the operation is a bitwise operation used in a boolean
-  ///          context (both operands are boolean, or it assigns to boolean),
-  ///          false otherwise.
-  bool isBooleanBitwise(const clang::BinaryOperator *BinOp,
-                        bool AssignsToBoolean) {
-    if (!BinOp)
-      return false;
-
-    if (!isBitwiseOperation(BinOp->getOpcodeStr()))
-      return false;
-
-    auto IsBooleanType = [&](const clang::Expr *E) {
-      return E->IgnoreImpCasts()
-          ->getType()
-          .getDesugaredType(Ctx)
-          ->isBooleanType();
-    };
-    const bool IsBooleanLHS = allLeavesSatisfy(BinOp->getLHS(), IsBooleanType);
-    const bool IsBooleanRHS = allLeavesSatisfy(BinOp->getRHS(), IsBooleanType);
-
-    // If both operands are boolean, this is definitely a boolean bitwise
-    // operation. Preserve the existing RootAssignsToBoolean value if set,
-    // otherwise set it to false (no assignment context).
-    if (IsBooleanLHS && IsBooleanRHS)
-      return true;
-
-    // Check if this operation assigns to a boolean type. This includes:
-    // 1. Operations where at least one operand is boolean and the result is
-    //    assigned to boolean (e.g., `bool x = a | b` where a is int and b is
-    //    boolean)
-    // 2. Compound assignments where the LHS is boolean (e.g., `x |= y` where
-    // y is int and x is boolean)
-    const bool IsRelevantAssignmentToBoolean =
-        ((IsBooleanLHS || IsBooleanRHS) && AssignsToBoolean) ||
-        (IsBooleanLHS && BinOp->isCompoundAssignmentOp());
-
-    // If this operation assigns to boolean, then this is a boolean bitwise
-    // operation. Set RootAssignsToBoolean to true to propagate this
-    // information up the call stack.
-    return IsRelevantAssignmentToBoolean;
-  }
-
   bool TraverseBinaryOperator(clang::BinaryOperator *BinOp) override {
     if (!BinOp)
       return true;
@@ -346,18 +335,14 @@ class BinaryOperatorVisitor : public clang::DynamicRecursiveASTVisitor {
 void BoolBitwiseOperationCheck::check(const MatchFinder::MatchResult &Result) {
   const auto *BinOpRoot = Result.Nodes.getNodeAs<BinaryOperator>("binOpRoot");
   const auto *ParentRoot = Result.Nodes.getNodeAs<BinaryOperator>("p");
-  const bool AssignsToBoolean =
-      Result.Nodes.getMap().find("ice") != Result.Nodes.getMap().end();
   assert(BinOpRoot);
 
   const SourceManager &SM = *Result.SourceManager;
   ASTContext &Ctx = *Result.Context;
 
   BinaryOperatorVisitor Visitor(*this, SM, Ctx, ParentRoot);
-  if (Visitor.isBooleanBitwise(BinOpRoot, AssignsToBoolean)) {
-    // TraverseStmt requires non-const pointer, but we're only reading
-    Visitor.TraverseStmt(const_cast<BinaryOperator *>(BinOpRoot));
-  }
+  // TraverseStmt requires non-const pointer, but we're only reading
+  Visitor.TraverseStmt(const_cast<BinaryOperator *>(BinOpRoot));
 }
 
 } // namespace clang::tidy::misc

>From 6d390139e39fb92aebbcc787c845257193b648b0 Mon Sep 17 00:00:00 2001
From: denzor200 <denismikhaylov38 at gmail.com>
Date: Sat, 17 Jan 2026 09:32:09 +0300
Subject: [PATCH 39/49] change comments

---
 .../clang-tidy/misc/BoolBitwiseOperationCheck.cpp             | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.cpp b/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.cpp
index bc69853f271b2..e66f571d78c84 100644
--- a/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.cpp
+++ b/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.cpp
@@ -110,9 +110,11 @@ void BoolBitwiseOperationCheck::registerMatchers(MatchFinder *Finder) {
   auto NotNestedInBitwise = unless(hasParent(binaryOperator(BitwiseOps)));
   auto OptionalParent = optionally(hasParent(binaryOperator().bind("p")));
 
-  // Conditions that make it a boolean bitwise operation without ICE context:
+  // Conditions that make it a boolean bitwise operation without ICE(*) context:
   // 1. Both LHS and RHS have all boolean leaves
   // 2. LHS has boolean leaves AND it's a compound assignment
+  //
+  // * ICE - Implicit cast expression
   auto BothBoolean = allOf(hasLHS(BooleanLeaves), hasRHS(BooleanLeaves));
   auto CompoundWithBoolLHS = allOf(hasLHS(BooleanLeaves), CompoundBitwiseOps);
   auto NoContextNeeded = anyOf(BothBoolean, CompoundWithBoolLHS);

>From f84b2d82613178b829daf26b9d43b897622e2d0d Mon Sep 17 00:00:00 2001
From: denzor200 <denismikhaylov38 at gmail.com>
Date: Sat, 17 Jan 2026 11:00:29 +0300
Subject: [PATCH 40/49] More tests for volatile && simplify

---
 .../misc/BoolBitwiseOperationCheck.cpp        |  1 -
 .../bool-bitwise-operation-nontraditional.cpp | 81 +++++++++++++++++++
 .../checkers/misc/bool-bitwise-operation.cpp  | 81 +++++++++++++++++++
 3 files changed, 162 insertions(+), 1 deletion(-)

diff --git a/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.cpp b/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.cpp
index e66f571d78c84..7301e4dd1f5b3 100644
--- a/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.cpp
+++ b/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.cpp
@@ -157,7 +157,6 @@ void BoolBitwiseOperationCheck::emitWarningAndChangeOperatorsIfPossible(
       std::array{BinOp->getLHS(), BinOp->getRHS()}, [&](const Expr *E) {
         return E->IgnoreImpCasts()
             ->getType()
-            .getDesugaredType(Ctx)
             .isVolatileQualified();
       });
   if (HasVolatileOperand) {
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 4a0581b6f194a..94d67a939d356 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
@@ -122,6 +122,22 @@ void bad_side_effects() {
     // CHECK-MESSAGES-NOT: :[[@LINE-2]]:{{.*}}: note: FIX-IT applied suggested code changes
 }
 
+void bad_pointers() {
+    bool pointee = false;
+    bool* a = &pointee;
+    bool* b = &pointee;
+    *a bitor *b;
+    // CHECK-MESSAGES: :[[@LINE-1]]:8: 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]]:8: warning: use logical operator '&&' for boolean semantics instead of bitwise operator '&' [misc-bool-bitwise-operation]
+    // CHECK-FIXES: *a and *b;
+
+    // FIXME: implement fixit for these 2 cases
+    // *a or_eq *b;
+    // *a and_eq *b;
+}
+
 void bad_side_effects_volatile() {
     bool a = true;
     volatile bool b = false;
@@ -152,6 +168,71 @@ void bad_side_effects_volatile() {
     // CHECK-FIXES: a or c bitor b;
 }
 
+void bad_side_effects_volatile_typedef() {
+    using volatile_bool_t = volatile bool;
+    bool a = true;
+    volatile_bool_t b = false;
+    bool c = true;
+
+    a bitor b;
+    // 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 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;
+    // 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 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;
+    // 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 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_side_effects_volatile_typedef_pointers() {
+    using volatile_bool_t = volatile bool;
+    bool pointee = false;
+    volatile_bool_t* a = &pointee;
+    volatile_bool_t* b = &pointee;
+    *a bitor *b;
+    // CHECK-MESSAGES: :[[@LINE-1]]:8: 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]]:8: 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
+
+    // FIXME: implement fixit for these 2 cases
+    // *a or_eq *b;
+    // *a and_eq *b;
+}
+
+void bad_side_effects_volatile_typedef_pointers_2() {
+    using volatile_bool_t = volatile bool*;
+    bool pointee = false;
+    volatile_bool_t a = &pointee;
+    volatile_bool_t b = &pointee;
+    *a bitor *b;
+    // CHECK-MESSAGES: :[[@LINE-1]]:8: 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]]:8: 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
+
+    // FIXME: implement fixit for these 2 cases
+    // *a or_eq *b;
+    // *a and_eq *b;
+}
+
 void bad_with_priors() {
     bool a = false, b = true, c = true;
     a and b bitor c;
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 2c30de717d41e..350c3a0669f39 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
@@ -122,6 +122,22 @@ void bad_side_effects() {
     // CHECK-MESSAGES-NOT: :[[@LINE-2]]:{{.*}}: note: FIX-IT applied suggested code changes
 }
 
+void bad_pointers() {
+    bool pointee = false;
+    bool* a = &pointee;
+    bool* b = &pointee;
+    *a | *b;
+    // CHECK-MESSAGES: :[[@LINE-1]]:8: 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]]:8: warning: use logical operator '&&' for boolean semantics instead of bitwise operator '&' [misc-bool-bitwise-operation]
+    // CHECK-FIXES: *a && *b;
+
+    // FIXME: implement fixit for these 2 cases
+    // *a |= *b;
+    // *a &= *b;
+}
+
 void bad_side_effects_volatile() {
     bool a = true;
     volatile bool b = false;
@@ -152,6 +168,71 @@ void bad_side_effects_volatile() {
     // CHECK-FIXES: a || c | b;
 }
 
+void bad_side_effects_volatile_typedef() {
+    using volatile_bool_t = volatile bool;
+    bool a = true;
+    volatile_bool_t b = false;
+    bool c = true;
+
+    a | b;
+    // 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 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 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 semantics instead of bitwise operator '&=' [misc-bool-bitwise-operation]
+    // 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 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 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_side_effects_volatile_typedef_pointers() {
+    using volatile_bool_t = volatile bool;
+    bool pointee = false;
+    volatile_bool_t* a = &pointee;
+    volatile_bool_t* b = &pointee;
+    *a | *b;
+    // CHECK-MESSAGES: :[[@LINE-1]]:8: 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]]:8: 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
+
+    // FIXME: implement fixit for these 2 cases
+    // *a |= *b;
+    // *a &= *b;
+}
+
+void bad_side_effects_volatile_typedef_pointers_2() {
+    using volatile_bool_t = volatile bool*;
+    bool pointee = false;
+    volatile_bool_t a = &pointee;
+    volatile_bool_t b = &pointee;
+    *a | *b;
+    // CHECK-MESSAGES: :[[@LINE-1]]:8: 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]]:8: 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
+
+    // FIXME: implement fixit for these 2 cases
+    // *a |= *b;
+    // *a &= *b;
+}
+
 void bad_with_priors() {
     bool a = false, b = true, c = true;
     a && b | c;

>From 61ac0b178383f3981f862b1822b18935f8cc14da Mon Sep 17 00:00:00 2001
From: denzor200 <denismikhaylov38 at gmail.com>
Date: Sat, 17 Jan 2026 11:44:10 +0300
Subject: [PATCH 41/49] refactoring

---
 .../misc/BoolBitwiseOperationCheck.cpp        | 103 ++++++++++--------
 1 file changed, 55 insertions(+), 48 deletions(-)

diff --git a/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.cpp b/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.cpp
index 7301e4dd1f5b3..dfb6b3672240a 100644
--- a/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.cpp
+++ b/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.cpp
@@ -11,7 +11,6 @@
 #include "clang/ASTMatchers/ASTMatchFinder.h"
 #include "clang/Lex/Lexer.h"
 #include <array>
-#include <optional>
 #include <utility>
 #include <vector>
 
@@ -153,6 +152,17 @@ void BoolBitwiseOperationCheck::emitWarningAndChangeOperatorsIfPossible(
            << translate(BinOp->getOpcodeStr()) << BinOp->getOpcodeStr();
   };
 
+  // Helper lambda to check if location is valid and not in a macro
+  auto IsValidLocation = [&](SourceLocation Loc) -> bool {
+    if (Loc.isInvalid() || Loc.isMacroID()) {
+      if (!IgnoreMacros)
+        DiagEmitter();
+      return false;
+    }
+    return true;
+  };
+
+  // Early validation: check for volatile operands
   const bool HasVolatileOperand = llvm::any_of(
       std::array{BinOp->getLHS(), BinOp->getRHS()}, [&](const Expr *E) {
         return E->IgnoreImpCasts()
@@ -164,108 +174,105 @@ void BoolBitwiseOperationCheck::emitWarningAndChangeOperatorsIfPossible(
     return;
   }
 
+  // Early validation: check for side effects
   const bool HasSideEffects = BinOp->getRHS()->HasSideEffects(
-      Ctx, /*IncludePossibleEffects=*/!UnsafeMode);
+    Ctx, /*IncludePossibleEffects=*/!UnsafeMode);
   if (HasSideEffects) {
     DiagEmitter();
     return;
   }
 
-  SourceLocation Loc = BinOp->getOperatorLoc();
-
-  if (Loc.isInvalid() || Loc.isMacroID()) {
-    IgnoreMacros || DiagEmitter();
+  // Get and validate operator location
+  SourceLocation OpLoc = BinOp->getOperatorLoc();
+  if (!IsValidLocation(OpLoc))
     return;
-  }
 
-  Loc = SM.getSpellingLoc(Loc);
-  if (Loc.isInvalid() || Loc.isMacroID()) {
-    IgnoreMacros || DiagEmitter();
+  OpLoc = SM.getSpellingLoc(OpLoc);
+  if (!IsValidLocation(OpLoc))
     return;
-  }
 
-  const CharSourceRange TokenRange = CharSourceRange::getTokenRange(Loc);
+  // Generate fix-it hint for operator replacement
+  const CharSourceRange TokenRange = CharSourceRange::getTokenRange(OpLoc);
   if (TokenRange.isInvalid()) {
-    IgnoreMacros || DiagEmitter();
+    if (!IgnoreMacros)
+      DiagEmitter();
     return;
   }
 
   const StringRef FixSpelling =
       translate(Lexer::getSourceText(TokenRange, SM, Ctx.getLangOpts()));
-
   if (FixSpelling.empty()) {
     DiagEmitter();
     return;
   }
 
-  FixItHint InsertEqual;
+  FixItHint ReplaceOpHint = FixItHint::CreateReplacement(TokenRange, FixSpelling);
+
+  // Generate fix-it hint for compound assignment (if applicable)
+  FixItHint InsertEqualHint;
   if (BinOp->isCompoundAssignmentOp()) {
     const auto *LHS = getAcceptableCompoundsLHS(BinOp);
     if (!LHS) {
       DiagEmitter();
       return;
     }
+
     const SourceLocation LocLHS = LHS->getEndLoc();
-    if (LocLHS.isInvalid() || LocLHS.isMacroID()) {
-      IgnoreMacros || DiagEmitter();
+    if (!IsValidLocation(LocLHS))
       return;
-    }
+
     const SourceLocation InsertLoc =
         clang::Lexer::getLocForEndOfToken(LocLHS, 0, SM, Ctx.getLangOpts());
-    if (InsertLoc.isInvalid() || InsertLoc.isMacroID()) {
-      IgnoreMacros || DiagEmitter();
+    if (!IsValidLocation(InsertLoc))
       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); });
-    InsertEqual = FixItHint::CreateInsertion(InsertLoc, " = " + SourceText);
+    InsertEqualHint = FixItHint::CreateInsertion(InsertLoc, " = " + SourceText);
   }
 
-  auto ReplaceOperator = FixItHint::CreateReplacement(TokenRange, FixSpelling);
-
-  std::optional<BinaryOperatorKind> ParentOpcode;
-  if (ParentBinOp)
-    ParentOpcode = ParentBinOp->getOpcode();
-
-  const auto *RHS = dyn_cast<BinaryOperator>(BinOp->getRHS()->IgnoreImpCasts());
-  std::optional<BinaryOperatorKind> RHSOpcode;
-  if (RHS)
-    RHSOpcode = RHS->getOpcode();
-
+  // Determine if parentheses are needed based on operator precedence
   const Expr *SurroundedExpr = nullptr;
-  if ((BinOp->getOpcode() == BO_Or && ParentOpcode == BO_LAnd) ||
-      (BinOp->getOpcode() == BO_And &&
-       llvm::is_contained({BO_Xor, BO_Or}, ParentOpcode))) {
-    const Expr *Side = ParentBinOp->getLHS()->IgnoreParenImpCasts() == BinOp
-                           ? ParentBinOp->getLHS()
-                           : ParentBinOp->getRHS();
-    SurroundedExpr = Side->IgnoreImpCasts();
-    assert(SurroundedExpr->IgnoreParens() == BinOp);
-  } else if (BinOp->getOpcode() == BO_AndAssign && RHSOpcode == BO_LOr)
-    SurroundedExpr = RHS;
+  if (ParentBinOp) {
+    const BinaryOperatorKind ParentOpcode = ParentBinOp->getOpcode();
+    if ((BinOp->getOpcode() == BO_Or && ParentOpcode == BO_LAnd) ||
+        (BinOp->getOpcode() == BO_And &&
+         llvm::is_contained({BO_Xor, BO_Or}, ParentOpcode))) {
+      const Expr *Side = ParentBinOp->getLHS()->IgnoreParenImpCasts() == BinOp
+                             ? ParentBinOp->getLHS()
+                             : ParentBinOp->getRHS();
+      SurroundedExpr = Side->IgnoreImpCasts();
+      assert(SurroundedExpr->IgnoreParens() == BinOp);
+    }
+  }
+
+  if (!SurroundedExpr) {
+    const auto *RHS = dyn_cast<BinaryOperator>(BinOp->getRHS()->IgnoreImpCasts());
+    if (RHS && BinOp->getOpcode() == BO_AndAssign && RHS->getOpcode() == BO_LOr)
+      SurroundedExpr = RHS;
+  }
 
   if (isa_and_nonnull<ParenExpr>(SurroundedExpr))
     SurroundedExpr = nullptr;
 
+  // Generate fix-it hints for parentheses (if needed)
   FixItHint InsertBrace1;
   FixItHint InsertBrace2;
   if (SurroundedExpr) {
     const SourceLocation InsertFirstLoc = SurroundedExpr->getBeginLoc();
     const SourceLocation InsertSecondLoc = clang::Lexer::getLocForEndOfToken(
         SurroundedExpr->getEndLoc(), 0, SM, Ctx.getLangOpts());
-    if (InsertFirstLoc.isInvalid() || InsertFirstLoc.isMacroID() ||
-        InsertSecondLoc.isInvalid() || InsertSecondLoc.isMacroID()) {
-      IgnoreMacros || DiagEmitter();
+    if (!IsValidLocation(InsertFirstLoc) || !IsValidLocation(InsertSecondLoc))
       return;
-    }
+
     InsertBrace1 = FixItHint::CreateInsertion(InsertFirstLoc, "(");
     InsertBrace2 = FixItHint::CreateInsertion(InsertSecondLoc, ")");
   }
 
-  DiagEmitter() << InsertEqual << ReplaceOperator << InsertBrace1
+  DiagEmitter() << InsertEqualHint << ReplaceOpHint << InsertBrace1
                 << InsertBrace2;
 }
 

>From 030cf62a9085fb7506dae379bdc90f035df50b13 Mon Sep 17 00:00:00 2001
From: denzor200 <denismikhaylov38 at gmail.com>
Date: Sat, 17 Jan 2026 12:15:36 +0300
Subject: [PATCH 42/49] Add StrictMode option

---
 .../misc/BoolBitwiseOperationCheck.cpp        | 21 ++++++---
 .../misc/BoolBitwiseOperationCheck.h          |  1 +
 .../checks/misc/bool-bitwise-operation.rst    |  9 +++-
 ...bitwise-operation-strict-mode-disabled.cpp | 47 +++++++++++++++++++
 4 files changed, 70 insertions(+), 8 deletions(-)
 create mode 100644 clang-tools-extra/test/clang-tidy/checkers/misc/bool-bitwise-operation-strict-mode-disabled.cpp

diff --git a/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.cpp b/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.cpp
index dfb6b3672240a..0b0fc2a36c1c5 100644
--- a/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.cpp
+++ b/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.cpp
@@ -92,12 +92,14 @@ BoolBitwiseOperationCheck::BoolBitwiseOperationCheck(StringRef Name,
                                                      ClangTidyContext *Context)
     : ClangTidyCheck(Name, Context),
       UnsafeMode(Options.get("UnsafeMode", false)),
-      IgnoreMacros(Options.get("IgnoreMacros", false)) {}
+      IgnoreMacros(Options.get("IgnoreMacros", false)),
+      StrictMode(Options.get("StrictMode", true)) {}
 
 void BoolBitwiseOperationCheck::storeOptions(
     ClangTidyOptions::OptionMap &Opts) {
   Options.store(Opts, "UnsafeMode", UnsafeMode);
   Options.store(Opts, "IgnoreMacros", IgnoreMacros);
+  Options.store(Opts, "StrictMode", StrictMode);
 }
 
 void BoolBitwiseOperationCheck::registerMatchers(MatchFinder *Finder) {
@@ -152,11 +154,16 @@ void BoolBitwiseOperationCheck::emitWarningAndChangeOperatorsIfPossible(
            << translate(BinOp->getOpcodeStr()) << BinOp->getOpcodeStr();
   };
 
+  auto DiagEmitterForStrictMode = [&] {
+    if (StrictMode)
+      DiagEmitter();
+  };
+
   // Helper lambda to check if location is valid and not in a macro
   auto IsValidLocation = [&](SourceLocation Loc) -> bool {
     if (Loc.isInvalid() || Loc.isMacroID()) {
       if (!IgnoreMacros)
-        DiagEmitter();
+        DiagEmitterForStrictMode();
       return false;
     }
     return true;
@@ -170,7 +177,7 @@ void BoolBitwiseOperationCheck::emitWarningAndChangeOperatorsIfPossible(
             .isVolatileQualified();
       });
   if (HasVolatileOperand) {
-    DiagEmitter();
+    DiagEmitterForStrictMode();
     return;
   }
 
@@ -178,7 +185,7 @@ void BoolBitwiseOperationCheck::emitWarningAndChangeOperatorsIfPossible(
   const bool HasSideEffects = BinOp->getRHS()->HasSideEffects(
     Ctx, /*IncludePossibleEffects=*/!UnsafeMode);
   if (HasSideEffects) {
-    DiagEmitter();
+    DiagEmitterForStrictMode();
     return;
   }
 
@@ -195,14 +202,14 @@ void BoolBitwiseOperationCheck::emitWarningAndChangeOperatorsIfPossible(
   const CharSourceRange TokenRange = CharSourceRange::getTokenRange(OpLoc);
   if (TokenRange.isInvalid()) {
     if (!IgnoreMacros)
-      DiagEmitter();
+      DiagEmitterForStrictMode();
     return;
   }
 
   const StringRef FixSpelling =
       translate(Lexer::getSourceText(TokenRange, SM, Ctx.getLangOpts()));
   if (FixSpelling.empty()) {
-    DiagEmitter();
+    DiagEmitterForStrictMode();
     return;
   }
 
@@ -213,7 +220,7 @@ void BoolBitwiseOperationCheck::emitWarningAndChangeOperatorsIfPossible(
   if (BinOp->isCompoundAssignmentOp()) {
     const auto *LHS = getAcceptableCompoundsLHS(BinOp);
     if (!LHS) {
-      DiagEmitter();
+      DiagEmitterForStrictMode();
       return;
     }
 
diff --git a/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.h b/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.h
index b3977a3d41824..3defcf8461969 100644
--- a/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.h
+++ b/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.h
@@ -36,6 +36,7 @@ class BoolBitwiseOperationCheck : public ClangTidyCheck {
 private:
   bool UnsafeMode;
   bool IgnoreMacros;
+  bool StrictMode;
 };
 
 } // namespace clang::tidy::misc
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 f7f03575ae126..f401bea4b7f53 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
@@ -73,4 +73,11 @@ Options
 .. option:: IgnoreMacros
 
     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
+    bitwise operator with a logical one. Default value is `false`.
+
+.. option:: StrictMode
+
+    When enabled, show warnings even when fix-it hints cannot be generated
+    (e.g., for volatile operands or expressions with side effects). When
+    disabled, only show warnings when fix-it hints are available. Default
+    value is `true`.
\ No newline at end of file
diff --git a/clang-tools-extra/test/clang-tidy/checkers/misc/bool-bitwise-operation-strict-mode-disabled.cpp b/clang-tools-extra/test/clang-tidy/checkers/misc/bool-bitwise-operation-strict-mode-disabled.cpp
new file mode 100644
index 0000000000000..0e2c36d3937c1
--- /dev/null
+++ b/clang-tools-extra/test/clang-tidy/checkers/misc/bool-bitwise-operation-strict-mode-disabled.cpp
@@ -0,0 +1,47 @@
+// RUN: %check_clang_tidy %s misc-bool-bitwise-operation %t \
+// RUN:   -config="{CheckOptions: { \
+// RUN:     misc-bool-bitwise-operation.StrictMode: false }}"
+
+// Test with StrictMode=false: warnings should NOT be shown when fixits don't exist
+
+bool function_with_possible_side_effects();
+
+void test_strict_mode_disabled() {
+    bool a = true, b = false;
+
+    // Case 1: Side effects in RHS - no fixit, no warning should be shown
+    a | function_with_possible_side_effects();
+    // CHECK-MESSAGES-NOT: :[[@LINE-1]]:{{.*}}: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
+
+    a & function_with_possible_side_effects();
+    // CHECK-MESSAGES-NOT: :[[@LINE-1]]:{{.*}}: warning: use logical operator '&&' for boolean semantics instead of bitwise operator '&' [misc-bool-bitwise-operation]
+
+    a |= function_with_possible_side_effects();
+    // CHECK-MESSAGES-NOT: :[[@LINE-1]]:{{.*}}: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|=' [misc-bool-bitwise-operation]
+
+    a &= function_with_possible_side_effects();
+    // CHECK-MESSAGES-NOT: :[[@LINE-1]]:{{.*}}: warning: use logical operator '&&' for boolean semantics instead of bitwise operator '&=' [misc-bool-bitwise-operation]
+
+    // Case 2: Volatile operands - no fixit, no warning should be shown
+    volatile bool v = false;
+    a | v;
+    // CHECK-MESSAGES-NOT: :[[@LINE-1]]:{{.*}}: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
+
+    a & v;
+    // CHECK-MESSAGES-NOT: :[[@LINE-1]]:{{.*}}: warning: use logical operator '&&' for boolean semantics instead of bitwise operator '&' [misc-bool-bitwise-operation]
+
+    a |= v;
+    // CHECK-MESSAGES-NOT: :[[@LINE-1]]:{{.*}}: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|=' [misc-bool-bitwise-operation]
+
+    a &= v;
+    // CHECK-MESSAGES-NOT: :[[@LINE-1]]:{{.*}}: warning: use logical operator '&&' for boolean semantics instead of bitwise operator '&=' [misc-bool-bitwise-operation]
+
+    // Case 3: Normal case with fixit - warning should still be shown with fixit
+    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 || b;
+
+    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 && b;
+}

>From 515b364dcc9ddf15621744bc761e2a7838b9c847 Mon Sep 17 00:00:00 2001
From: denzor200 <denismikhaylov38 at gmail.com>
Date: Sat, 17 Jan 2026 12:16:33 +0300
Subject: [PATCH 43/49] format

---
 .../misc/BoolBitwiseOperationCheck.cpp        | 47 ++++++++++---------
 1 file changed, 24 insertions(+), 23 deletions(-)

diff --git a/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.cpp b/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.cpp
index 0b0fc2a36c1c5..9854360c1eb01 100644
--- a/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.cpp
+++ b/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.cpp
@@ -48,16 +48,17 @@ static const Expr *getAcceptableCompoundsLHS(const BinaryOperator *BinOp) {
   return isa<DeclRefExpr, MemberExpr>(LHS) ? LHS : nullptr;
 }
 
-/// Checks if all leaf nodes in an bitwise expression satisfy a given condition. This
-/// handles cases like `(a | b) & c` where we need to check that a, b, and c
-/// all satisfy the condition.
+/// Checks if all leaf nodes in an bitwise expression satisfy a given condition.
+/// This handles cases like `(a | b) & c` where we need to check that a, b, and
+/// c all satisfy the condition.
 ///
 /// \param Expr The bitwise expression to check.
 /// \param Condition A function that checks if an leaf node satisfies the
 ///                  desired condition.
 /// \returns true if all leaf nodes satisfy the condition, false otherwise.
 template <typename F>
-static bool allLeavesOfBitwiseSatisfy(const clang::Expr *Expr, const F& Condition) {
+static bool allLeavesOfBitwiseSatisfy(const clang::Expr *Expr,
+                                      const F &Condition) {
   // For leaf nodes, check if the condition is satisfied
   if (Condition(Expr))
     return true;
@@ -69,14 +70,15 @@ static bool allLeavesOfBitwiseSatisfy(const clang::Expr *Expr, const F& Conditio
     if (!isBitwiseOperation(BinOp->getOpcodeStr()))
       return false;
     return allLeavesOfBitwiseSatisfy(BinOp->getLHS(), Condition) &&
-            allLeavesOfBitwiseSatisfy(BinOp->getRHS(), Condition);
+           allLeavesOfBitwiseSatisfy(BinOp->getRHS(), Condition);
   }
 
   return false;
 }
 
-/// Custom matcher that checks if all leaf nodes in an bitwise expression satisfy
-/// the given inner matcher condition. This uses allLeavesOfBitwiseSatisfy to recursively
+/// Custom matcher that checks if all leaf nodes in an bitwise expression
+/// satisfy the given inner matcher condition. This uses
+/// allLeavesOfBitwiseSatisfy to recursively
 ///
 /// Example usage:
 ///   expr(hasAllLeavesOfBitwiseSatisfying(hasType(booleanType())))
@@ -125,19 +127,18 @@ void BoolBitwiseOperationCheck::registerMatchers(MatchFinder *Finder) {
   auto AtLeastOneBoolean = anyOf(hasLHS(BooleanLeaves), hasRHS(BooleanLeaves));
 
   // Matcher for binop that doesn't need ICE context
-  auto BinOpNoContext = traverse(
-      TK_IgnoreUnlessSpelledInSource,
-      binaryOperator(NotNestedInBitwise, BitwiseOps, OptionalParent,
-                     NoContextNeeded)
-          .bind("binOpRoot"));
+  auto BinOpNoContext = traverse(TK_IgnoreUnlessSpelledInSource,
+                                 binaryOperator(NotNestedInBitwise, BitwiseOps,
+                                                OptionalParent, NoContextNeeded)
+                                     .bind("binOpRoot"));
 
   // Matcher for binop that needs ICE context (at least one boolean operand,
   // but not already covered by NoContextNeeded)
-  auto BinOpNeedsContext = traverse(
-      TK_IgnoreUnlessSpelledInSource,
-      binaryOperator(NotNestedInBitwise, BitwiseOps, OptionalParent,
-                     AtLeastOneBoolean, unless(NoContextNeeded))
-          .bind("binOpRoot"));
+  auto BinOpNeedsContext =
+      traverse(TK_IgnoreUnlessSpelledInSource,
+               binaryOperator(NotNestedInBitwise, BitwiseOps, OptionalParent,
+                              AtLeastOneBoolean, unless(NoContextNeeded))
+                   .bind("binOpRoot"));
   auto BooleanICE =
       implicitCastExpr(hasType(booleanType()), has(BinOpNeedsContext));
 
@@ -172,9 +173,7 @@ void BoolBitwiseOperationCheck::emitWarningAndChangeOperatorsIfPossible(
   // Early validation: check for volatile operands
   const bool HasVolatileOperand = llvm::any_of(
       std::array{BinOp->getLHS(), BinOp->getRHS()}, [&](const Expr *E) {
-        return E->IgnoreImpCasts()
-            ->getType()
-            .isVolatileQualified();
+        return E->IgnoreImpCasts()->getType().isVolatileQualified();
       });
   if (HasVolatileOperand) {
     DiagEmitterForStrictMode();
@@ -183,7 +182,7 @@ void BoolBitwiseOperationCheck::emitWarningAndChangeOperatorsIfPossible(
 
   // Early validation: check for side effects
   const bool HasSideEffects = BinOp->getRHS()->HasSideEffects(
-    Ctx, /*IncludePossibleEffects=*/!UnsafeMode);
+      Ctx, /*IncludePossibleEffects=*/!UnsafeMode);
   if (HasSideEffects) {
     DiagEmitterForStrictMode();
     return;
@@ -213,7 +212,8 @@ void BoolBitwiseOperationCheck::emitWarningAndChangeOperatorsIfPossible(
     return;
   }
 
-  FixItHint ReplaceOpHint = FixItHint::CreateReplacement(TokenRange, FixSpelling);
+  FixItHint ReplaceOpHint =
+      FixItHint::CreateReplacement(TokenRange, FixSpelling);
 
   // Generate fix-it hint for compound assignment (if applicable)
   FixItHint InsertEqualHint;
@@ -257,7 +257,8 @@ void BoolBitwiseOperationCheck::emitWarningAndChangeOperatorsIfPossible(
   }
 
   if (!SurroundedExpr) {
-    const auto *RHS = dyn_cast<BinaryOperator>(BinOp->getRHS()->IgnoreImpCasts());
+    const auto *RHS =
+        dyn_cast<BinaryOperator>(BinOp->getRHS()->IgnoreImpCasts());
     if (RHS && BinOp->getOpcode() == BO_AndAssign && RHS->getOpcode() == BO_LOr)
       SurroundedExpr = RHS;
   }

>From 18242190ce251fca35ef0741096c2da303fbd1e3 Mon Sep 17 00:00:00 2001
From: denzor200 <denismikhaylov38 at gmail.com>
Date: Sat, 17 Jan 2026 13:20:28 +0300
Subject: [PATCH 44/49] change tests

---
 .../checkers/misc/bool-bitwise-operation-nontraditional.cpp     | 2 --
 1 file changed, 2 deletions(-)

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 94d67a939d356..e403cd83b1ca4 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
@@ -260,11 +260,9 @@ 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 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 semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]

>From 51e7922e029af17cfec6dae264f5698f8d54c06e Mon Sep 17 00:00:00 2001
From: denzor200 <denismikhaylov38 at gmail.com>
Date: Sat, 17 Jan 2026 13:20:38 +0300
Subject: [PATCH 45/49] lint

---
 .../clang-tidy/checks/misc/bool-bitwise-operation.rst  | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

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 f401bea4b7f53..6ea6e827b797a 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
@@ -3,11 +3,11 @@
 misc-bool-bitwise-operation
 ===========================
 
-Finds potentially inefficient use of bitwise operators such as ``&``,  ``|`` 
-and their compound analogues on Boolean values where logical operators like 
+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 
+Bitwise operations on Booleans can incur unnecessary performance overhead due
 to implicit integer conversions and missed short-circuit evaluation.
 
 .. code-block:: c++
@@ -29,7 +29,7 @@ to implicit integer conversions and missed short-circuit evaluation.
     // error handling
   }
 
-These 3 warnings suggest assigning the result of a logical ``||`` operation 
+These 3 warnings suggest assigning the result of a logical ``||`` operation
 instead of using the ``|=`` operator:
 
 .. code-block:: c++
@@ -80,4 +80,4 @@ Options
     When enabled, show warnings even when fix-it hints cannot be generated
     (e.g., for volatile operands or expressions with side effects). When
     disabled, only show warnings when fix-it hints are available. Default
-    value is `true`.
\ No newline at end of file
+    value is `true`.

>From cb00072d9ce672742c29882e0b1738bb6bfdc1ba Mon Sep 17 00:00:00 2001
From: denzor200 <denismikhaylov38 at gmail.com>
Date: Sat, 17 Jan 2026 13:22:10 +0300
Subject: [PATCH 46/49] lint

---
 .../clang-tidy/misc/BoolBitwiseOperationCheck.cpp              | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.cpp b/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.cpp
index 9854360c1eb01..928d1eddf0789 100644
--- a/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.cpp
+++ b/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.cpp
@@ -29,10 +29,9 @@ static constexpr std::array<std::pair<StringRef, StringRef>, 8U>
                              {"or_eq", "or"}}};
 
 static StringRef translate(StringRef Value) {
-  for (const auto &[Bitwise, Logical] : OperatorsTransformation) {
+  for (const auto &[Bitwise, Logical] : OperatorsTransformation)
     if (Value == Bitwise)
       return Logical;
-  }
 
   return {};
 }

>From aea089b8612b185e6320ec6c00b5e050fa167e61 Mon Sep 17 00:00:00 2001
From: denzor200 <denismikhaylov38 at gmail.com>
Date: Sat, 17 Jan 2026 13:42:02 +0300
Subject: [PATCH 47/49] lint

---
 .../clang-tidy/misc/BoolBitwiseOperationCheck.cpp             | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.cpp b/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.cpp
index 928d1eddf0789..8ba29a8051490 100644
--- a/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.cpp
+++ b/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.cpp
@@ -75,6 +75,7 @@ static bool allLeavesOfBitwiseSatisfy(const clang::Expr *Expr,
   return false;
 }
 
+namespace {
 /// Custom matcher that checks if all leaf nodes in an bitwise expression
 /// satisfy the given inner matcher condition. This uses
 /// allLeavesOfBitwiseSatisfy to recursively
@@ -88,6 +89,7 @@ AST_MATCHER_P(Expr, hasAllLeavesOfBitwiseSatisfying,
   };
   return allLeavesOfBitwiseSatisfy(&Node, Condition);
 }
+} // namespace
 
 BoolBitwiseOperationCheck::BoolBitwiseOperationCheck(StringRef Name,
                                                      ClangTidyContext *Context)
@@ -211,7 +213,7 @@ void BoolBitwiseOperationCheck::emitWarningAndChangeOperatorsIfPossible(
     return;
   }
 
-  FixItHint ReplaceOpHint =
+  const FixItHint ReplaceOpHint =
       FixItHint::CreateReplacement(TokenRange, FixSpelling);
 
   // Generate fix-it hint for compound assignment (if applicable)

>From 67d7af177e5e50878a9080df6679f05ef9503220 Mon Sep 17 00:00:00 2001
From: denzor200 <denismikhaylov38 at gmail.com>
Date: Sat, 17 Jan 2026 16:21:09 +0300
Subject: [PATCH 48/49] Fix false positive

---
 .../misc/BoolBitwiseOperationCheck.cpp        |  52 ++--
 ...itwise-operation-not-only-bool-operand.cpp | 256 ++++++++++++++++++
 2 files changed, 292 insertions(+), 16 deletions(-)

diff --git a/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.cpp b/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.cpp
index 8ba29a8051490..ef52e87e043d0 100644
--- a/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.cpp
+++ b/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.cpp
@@ -11,6 +11,7 @@
 #include "clang/ASTMatchers/ASTMatchFinder.h"
 #include "clang/Lex/Lexer.h"
 #include <array>
+#include <functional>
 #include <utility>
 #include <vector>
 
@@ -47,17 +48,17 @@ static const Expr *getAcceptableCompoundsLHS(const BinaryOperator *BinOp) {
   return isa<DeclRefExpr, MemberExpr>(LHS) ? LHS : nullptr;
 }
 
-/// Checks if all leaf nodes in an bitwise expression satisfy a given condition.
-/// This handles cases like `(a | b) & c` where we need to check that a, b, and
-/// c all satisfy the condition.
+/// Checks if leaf nodes in a bitwise expression satisfy a given condition.
 ///
 /// \param Expr The bitwise expression to check.
-/// \param Condition A function that checks if an leaf node satisfies the
+/// \param Condition A function that checks if a leaf node satisfies the
 ///                  desired condition.
-/// \returns true if all leaf nodes satisfy the condition, false otherwise.
-template <typename F>
-static bool allLeavesOfBitwiseSatisfy(const clang::Expr *Expr,
-                                      const F &Condition) {
+/// \param Combine A function that combines results from LHS and RHS (e.g., &&
+/// for "all", || for "any").
+/// \returns true if the condition is satisfied according to the combiner logic.
+template <typename F, typename Combiner>
+static bool leavesOfBitwiseSatisfy(const clang::Expr *Expr, const F &Condition,
+                                   const Combiner &Combine) {
   // For leaf nodes, check if the condition is satisfied
   if (Condition(Expr))
     return true;
@@ -68,8 +69,8 @@ static bool allLeavesOfBitwiseSatisfy(const clang::Expr *Expr,
   if (const auto *BinOp = dyn_cast<clang::BinaryOperator>(Expr)) {
     if (!isBitwiseOperation(BinOp->getOpcodeStr()))
       return false;
-    return allLeavesOfBitwiseSatisfy(BinOp->getLHS(), Condition) &&
-           allLeavesOfBitwiseSatisfy(BinOp->getRHS(), Condition);
+    return Combine(leavesOfBitwiseSatisfy(BinOp->getLHS(), Condition, Combine),
+                   leavesOfBitwiseSatisfy(BinOp->getRHS(), Condition, Combine));
   }
 
   return false;
@@ -78,7 +79,7 @@ static bool allLeavesOfBitwiseSatisfy(const clang::Expr *Expr,
 namespace {
 /// Custom matcher that checks if all leaf nodes in an bitwise expression
 /// satisfy the given inner matcher condition. This uses
-/// allLeavesOfBitwiseSatisfy to recursively
+/// leavesOfBitwiseSatisfy to recursively check.
 ///
 /// Example usage:
 ///   expr(hasAllLeavesOfBitwiseSatisfying(hasType(booleanType())))
@@ -87,7 +88,21 @@ AST_MATCHER_P(Expr, hasAllLeavesOfBitwiseSatisfying,
   auto Condition = [&](const clang::Expr *E) -> bool {
     return InnerMatcher.matches(*E, Finder, Builder);
   };
-  return allLeavesOfBitwiseSatisfy(&Node, Condition);
+  return leavesOfBitwiseSatisfy(&Node, Condition, std::logical_and<bool>());
+}
+
+/// Custom matcher that checks if any leaf node in a bitwise expression
+/// satisfies the given inner matcher condition. This uses
+/// leavesOfBitwiseSatisfy to recursively check.
+///
+/// Example usage:
+///   expr(hasAnyLeafOfBitwiseSatisfying(hasType(booleanType())))
+AST_MATCHER_P(Expr, hasAnyLeafOfBitwiseSatisfying,
+              ast_matchers::internal::Matcher<Expr>, InnerMatcher) {
+  auto Condition = [&](const clang::Expr *E) -> bool {
+    return InnerMatcher.matches(*E, Finder, Builder);
+  };
+  return leavesOfBitwiseSatisfy(&Node, Condition, std::logical_or<bool>());
 }
 } // namespace
 
@@ -106,8 +121,12 @@ void BoolBitwiseOperationCheck::storeOptions(
 }
 
 void BoolBitwiseOperationCheck::registerMatchers(MatchFinder *Finder) {
-  // Matcher for checking if all leaves in an expression are boolean type
+  // Matcher for checking if all leaves in an bitwise expression are boolean
+  // type
   auto BooleanLeaves = hasAllLeavesOfBitwiseSatisfying(hasType(booleanType()));
+  // Matcher for checking if at least one leaf in an bitwise expression is
+  // boolean type
+  auto BooleanAnyLeaf = hasAnyLeafOfBitwiseSatisfying(hasType(booleanType()));
 
   auto BitwiseOps = hasAnyOperatorName("|", "&", "|=", "&=");
   auto CompoundBitwiseOps = hasAnyOperatorName("|=", "&=");
@@ -123,9 +142,10 @@ void BoolBitwiseOperationCheck::registerMatchers(MatchFinder *Finder) {
   auto CompoundWithBoolLHS = allOf(hasLHS(BooleanLeaves), CompoundBitwiseOps);
   auto NoContextNeeded = anyOf(BothBoolean, CompoundWithBoolLHS);
 
-  // At least one boolean operand (needs ICE context to be considered boolean
-  // bitwise)
-  auto AtLeastOneBoolean = anyOf(hasLHS(BooleanLeaves), hasRHS(BooleanLeaves));
+  // Check if any leaf in LHS or RHS is boolean (needs ICE context to be
+  // considered boolean bitwise)
+  auto AtLeastOneBoolean =
+      anyOf(hasLHS(BooleanAnyLeaf), hasRHS(BooleanAnyLeaf));
 
   // Matcher for binop that doesn't need ICE context
   auto BinOpNoContext = traverse(TK_IgnoreUnlessSpelledInSource,
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 c3b6744c1cb14..c90514dc69f2c 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,6 +12,16 @@ void general(unsigned flags, bool value) {
     flags = (flags << 1) | (flags << 2) | (flags << 4) | value;
     take_int((flags << 1) | value);
     take_int((flags << 1) | (flags << 2) | value);
+    value | (flags << 1);
+    flags = value | (flags << 1);
+    flags = value | (flags << 1) | (flags << 2);
+    flags = value | (flags << 1) | (flags << 2) | (flags << 4);
+    flags = (flags << 1) | value | (flags << 2);
+    flags = (flags << 1) | value | (flags << 2) | (flags << 4);
+    flags = (flags << 1) | (flags << 2) | value | (flags << 4);
+    take_int(value | (flags << 1));
+    take_int(value | (flags << 1) | (flags << 2));
+    take_int((flags << 1) | value | (flags << 2));
 }
 
 // FIXME: implement `template<bool bb=true|1>` cases
@@ -50,6 +60,47 @@ void assign_to_boolean(unsigned flags, bool value) {
     // 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;
+    bool result2 = value | (flags << 1);
+    // CHECK-MESSAGES: :[[@LINE-1]]:26: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
+    // CHECK-FIXES: bool result2 = value || (flags << 1);
+    bool a2 = value | (flags << 2),
+    // CHECK-MESSAGES: :[[@LINE-1]]:21: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
+    // CHECK-FIXES: bool a2 = value || (flags << 2),
+         b2 = value | (flags << 4),
+    // CHECK-MESSAGES: :[[@LINE-1]]:21: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
+    // CHECK-FIXES: b2 = value || (flags << 4),
+         c2 = value | (flags << 8);
+    // CHECK-MESSAGES: :[[@LINE-1]]:21: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
+    // CHECK-FIXES: c2 = value || (flags << 8);
+    result2 = value | (flags << 1);
+    // CHECK-MESSAGES: :[[@LINE-1]]:21: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
+    // CHECK-FIXES: result2 = value || (flags << 1);
+    take(value | (flags << 1));
+    // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
+    // CHECK-FIXES: take(value || (flags << 1));
+    result2 = value | (flags << 1) | (flags << 2);
+    // CHECK-MESSAGES: :[[@LINE-1]]:21: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
+    // CHECK-MESSAGES: :[[@LINE-2]]:36: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
+    // CHECK-FIXES: result2 = value || (flags << 1) || (flags << 2);
+    result2 = value | (flags << 1) | (flags << 2) | (flags << 4);
+    // CHECK-MESSAGES: :[[@LINE-1]]:21: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
+    // CHECK-MESSAGES: :[[@LINE-2]]:36: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
+    // CHECK-MESSAGES: :[[@LINE-3]]:51: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
+    // CHECK-FIXES: result2 = value || (flags << 1) || (flags << 2) || (flags << 4);
+    result2 = (flags << 1) | value | (flags << 2);
+    // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
+    // CHECK-MESSAGES: :[[@LINE-2]]:36: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
+    // CHECK-FIXES: result2 = (flags << 1) || value || (flags << 2);
+    result2 = (flags << 1) | value | (flags << 2) | (flags << 4);
+    // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
+    // CHECK-MESSAGES: :[[@LINE-2]]:36: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
+    // CHECK-MESSAGES: :[[@LINE-3]]:51: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
+    // CHECK-FIXES: result2 = (flags << 1) || value || (flags << 2) || (flags << 4);
+    result2 = (flags << 1) | (flags << 2) | value | (flags << 4);
+    // 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]]:51: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
+    // CHECK-FIXES: result2 = (flags << 1) || (flags << 2) || value || (flags << 4);
 }
 
 void assign_to_boolean_parens(unsigned flags, bool value) {
@@ -86,6 +137,47 @@ void assign_to_boolean_parens(unsigned flags, bool value) {
     // 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);
+    bool result2 = ((value | (flags << 1)));
+    // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
+    // CHECK-FIXES: bool result2 = ((value || (flags << 1)));
+    bool a2 = ((value | (flags << 2))),
+    // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
+    // CHECK-FIXES: bool a2 = ((value || (flags << 2))),
+         b2 = ((value | (flags << 4))),
+    // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
+    // CHECK-FIXES: b2 = ((value || (flags << 4))),
+         c2 = ((value | (flags << 8)));
+    // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
+    // CHECK-FIXES: c2 = ((value || (flags << 8)));
+    result2 = ((value | (flags << 1)));
+    // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
+    // CHECK-FIXES: result2 = ((value || (flags << 1)));
+    take(((value | (flags << 1))));
+    // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
+    // CHECK-FIXES: take(((value || (flags << 1))));
+    result2 = ((value | (flags << 1) | (flags << 2)));
+    // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
+    // CHECK-MESSAGES: :[[@LINE-2]]:38: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
+    // CHECK-FIXES: result2 = ((value || (flags << 1) || (flags << 2)));
+    result2 = ((value | (flags << 1) | (flags << 2) | (flags << 4)));
+    // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
+    // CHECK-MESSAGES: :[[@LINE-2]]:38: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
+    // CHECK-MESSAGES: :[[@LINE-3]]:53: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
+    // CHECK-FIXES: result2 = ((value || (flags << 1) || (flags << 2) || (flags << 4)));
+    result2 = (((flags << 1) | value | (flags << 2)));
+    // CHECK-MESSAGES: :[[@LINE-1]]:30: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
+    // CHECK-MESSAGES: :[[@LINE-2]]:38: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
+    // CHECK-FIXES: result2 = (((flags << 1) || value || (flags << 2)));
+    result2 = (((flags << 1) | value | (flags << 2) | (flags << 4)));
+    // CHECK-MESSAGES: :[[@LINE-1]]:30: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
+    // CHECK-MESSAGES: :[[@LINE-2]]:38: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
+    // CHECK-MESSAGES: :[[@LINE-3]]:53: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
+    // CHECK-FIXES: result2 = (((flags << 1) || value || (flags << 2) || (flags << 4)));
+    result2 = (((flags << 1) | (flags << 2) | value | (flags << 4)));
+    // CHECK-MESSAGES: :[[@LINE-1]]:30: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
+    // CHECK-MESSAGES: :[[@LINE-2]]:45: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
+    // CHECK-MESSAGES: :[[@LINE-3]]:53: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
+    // CHECK-FIXES: result2 = (((flags << 1) || (flags << 2) || value || (flags << 4)));
 }
 
 void assign_to_boolean_parens2(unsigned flags, bool value) {
@@ -122,6 +214,47 @@ void assign_to_boolean_parens2(unsigned flags, bool value) {
     // 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));
+    bool result2 = (((value | (flags << 1))));
+    // CHECK-MESSAGES: :[[@LINE-1]]:29: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
+    // CHECK-FIXES: bool result2 = (((value || (flags << 1))));
+    bool a2 = (((value | (flags << 2)))),
+    // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
+    // CHECK-FIXES: bool a2 = (((value || (flags << 2)))),
+         b2 = (((value | (flags << 4)))),
+    // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
+    // CHECK-FIXES: b2 = (((value || (flags << 4)))),
+         c2 = (((value | (flags << 8))));
+    // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
+    // CHECK-FIXES: c2 = (((value || (flags << 8))));
+    result2 = (((value | (flags << 1))));
+    // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
+    // CHECK-FIXES: result2 = (((value || (flags << 1))));
+    take((((value | (flags << 1)))));
+    // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
+    // CHECK-FIXES: take((((value || (flags << 1)))));
+    result2 = (((value | (flags << 1) | (flags << 2))));
+    // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
+    // CHECK-MESSAGES: :[[@LINE-2]]:39: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
+    // CHECK-FIXES: result2 = (((value || (flags << 1) || (flags << 2))));
+    result2 = (((value | (flags << 1) | (flags << 2) | (flags << 4))));
+    // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
+    // CHECK-MESSAGES: :[[@LINE-2]]:39: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
+    // CHECK-MESSAGES: :[[@LINE-3]]:54: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
+    // CHECK-FIXES: result2 = (((value || (flags << 1) || (flags << 2) || (flags << 4))));
+    result2 = ((((flags << 1) | value | (flags << 2))));
+    // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
+    // CHECK-MESSAGES: :[[@LINE-2]]:39: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
+    // CHECK-FIXES: result2 = ((((flags << 1) || value || (flags << 2))));
+    result2 = ((((flags << 1) | value | (flags << 2) | (flags << 4))));
+    // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
+    // CHECK-MESSAGES: :[[@LINE-2]]:39: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
+    // CHECK-MESSAGES: :[[@LINE-3]]:54: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
+    // CHECK-FIXES: result2 = ((((flags << 1) || value || (flags << 2) || (flags << 4))));
+    result2 = ((((flags << 1) | (flags << 2) | value | (flags << 4))));
+    // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
+    // CHECK-MESSAGES: :[[@LINE-2]]:46: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
+    // CHECK-MESSAGES: :[[@LINE-3]]:54: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
+    // CHECK-FIXES: result2 = ((((flags << 1) || (flags << 2) || value || (flags << 4))));
 }
 
 // functional cast
@@ -159,6 +292,47 @@ void assign_to_boolean_fcast(unsigned flags, bool value) {
     // 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);
+    bool result2 = bool((value | (flags << 1)));
+    // CHECK-MESSAGES: :[[@LINE-1]]:32: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
+    // CHECK-FIXES: bool result2 = bool((value || (flags << 1)));
+    bool a2 = bool((value | (flags << 2))),
+    // CHECK-MESSAGES: :[[@LINE-1]]:27: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
+    // CHECK-FIXES: bool a2 = bool((value || (flags << 2))),
+         b2 = bool((value | (flags << 4))),
+    // CHECK-MESSAGES: :[[@LINE-1]]:27: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
+    // CHECK-FIXES: b2 = bool((value || (flags << 4))),
+         c2 = bool((value | (flags << 8)));
+    // CHECK-MESSAGES: :[[@LINE-1]]:27: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
+    // CHECK-FIXES: c2 = bool((value || (flags << 8)));
+    result2 = bool((value | (flags << 1)));
+    // CHECK-MESSAGES: :[[@LINE-1]]:27: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
+    // CHECK-FIXES: result2 = bool((value || (flags << 1)));
+    take(bool((value | (flags << 1))));
+    // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
+    // CHECK-FIXES: take(bool((value || (flags << 1))));
+    result2 = bool((value | (flags << 1) | (flags << 2)));
+    // 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: result2 = bool((value || (flags << 1) || (flags << 2)));
+    result2 = bool((value | (flags << 1) | (flags << 2) | (flags << 4)));
+    // 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: result2 = bool((value || (flags << 1) || (flags << 2) || (flags << 4)));
+    result2 = bool(((flags << 1) | value | (flags << 2)));
+    // CHECK-MESSAGES: :[[@LINE-1]]:34: 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: result2 = bool(((flags << 1) || value || (flags << 2)));
+    result2 = bool(((flags << 1) | value | (flags << 2) | (flags << 4)));
+    // CHECK-MESSAGES: :[[@LINE-1]]:34: 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: result2 = bool(((flags << 1) || value || (flags << 2) || (flags << 4)));
+    result2 = bool(((flags << 1) | (flags << 2) | value | (flags << 4)));
+    // 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]]:57: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
+    // CHECK-FIXES: result2 = bool(((flags << 1) || (flags << 2) || value || (flags << 4)));
 }
 
 // C-style cast
@@ -196,6 +370,47 @@ void assign_to_boolean_ccast(unsigned flags, bool value) {
     // 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);
+    bool result2 = (bool)((value | (flags << 1)));
+    // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
+    // CHECK-FIXES: bool result2 = (bool)((value || (flags << 1)));
+    bool a2 = (bool)((value | (flags << 2))),
+    // CHECK-MESSAGES: :[[@LINE-1]]:29: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
+    // CHECK-FIXES: bool a2 = (bool)((value || (flags << 2))),
+         b2 = (bool)((value | (flags << 4))),
+    // CHECK-MESSAGES: :[[@LINE-1]]:29: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
+    // CHECK-FIXES: b2 = (bool)((value || (flags << 4))),
+         c2 = (bool)((value | (flags << 8)));
+    // CHECK-MESSAGES: :[[@LINE-1]]:29: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
+    // CHECK-FIXES: c2 = (bool)((value || (flags << 8)));
+    result2 = (bool)((value | (flags << 1)));
+    // CHECK-MESSAGES: :[[@LINE-1]]:29: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
+    // CHECK-FIXES: result2 = (bool)((value || (flags << 1)));
+    take((bool)((value | (flags << 1))));
+    // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
+    // CHECK-FIXES: take((bool)((value || (flags << 1))));
+    result2 = (bool)((value | (flags << 1) | (flags << 2)));
+    // 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: result2 = (bool)((value || (flags << 1) || (flags << 2)));
+    result2 = (bool)((value | (flags << 1) | (flags << 2) | (flags << 4)));
+    // 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: result2 = (bool)((value || (flags << 1) || (flags << 2) || (flags << 4)));
+    result2 = (bool)(((flags << 1) | value | (flags << 2)));
+    // CHECK-MESSAGES: :[[@LINE-1]]:36: 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: result2 = (bool)(((flags << 1) || value || (flags << 2)));
+    result2 = (bool)(((flags << 1) | value | (flags << 2) | (flags << 4)));
+    // CHECK-MESSAGES: :[[@LINE-1]]:36: 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: result2 = (bool)(((flags << 1) || value || (flags << 2) || (flags << 4)));
+    result2 = (bool)(((flags << 1) | (flags << 2) | value | (flags << 4)));
+    // CHECK-MESSAGES: :[[@LINE-1]]:36: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
+    // CHECK-MESSAGES: :[[@LINE-2]]:51: 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: result2 = (bool)(((flags << 1) || (flags << 2) || value || (flags << 4)));
 }
 
 // static_cast
@@ -233,6 +448,47 @@ void assign_to_boolean_scast(unsigned flags, bool value) {
     // 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);
+    bool result2 = static_cast<bool>((value | (flags << 1)));
+    // CHECK-MESSAGES: :[[@LINE-1]]:45: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
+    // CHECK-FIXES: bool result2 = static_cast<bool>((value || (flags << 1)));
+    bool a2 = static_cast<bool>((value | (flags << 2))),
+    // CHECK-MESSAGES: :[[@LINE-1]]:40: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
+    // CHECK-FIXES: bool a2 = static_cast<bool>((value || (flags << 2))),
+         b2 = static_cast<bool>((value | (flags << 4))),
+    // CHECK-MESSAGES: :[[@LINE-1]]:40: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
+    // CHECK-FIXES: b2 = static_cast<bool>((value || (flags << 4))),
+         c2 = static_cast<bool>((value | (flags << 8)));
+    // CHECK-MESSAGES: :[[@LINE-1]]:40: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
+    // CHECK-FIXES: c2 = static_cast<bool>((value || (flags << 8)));
+    result2 = static_cast<bool>((value | (flags << 1)));
+    // CHECK-MESSAGES: :[[@LINE-1]]:40: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
+    // CHECK-FIXES: result2 = static_cast<bool>((value || (flags << 1)));
+    take(static_cast<bool>((value | (flags << 1))));
+    // CHECK-MESSAGES: :[[@LINE-1]]:35: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
+    // CHECK-FIXES: take(static_cast<bool>((value || (flags << 1))));
+    result2 = static_cast<bool>((value | (flags << 1) | (flags << 2)));
+    // CHECK-MESSAGES: :[[@LINE-1]]:40: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
+    // CHECK-MESSAGES: :[[@LINE-2]]:55: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
+    // CHECK-FIXES: result2 = static_cast<bool>((value || (flags << 1) || (flags << 2)));
+    result2 = static_cast<bool>((value | (flags << 1) | (flags << 2) | (flags << 4)));
+    // CHECK-MESSAGES: :[[@LINE-1]]:40: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
+    // CHECK-MESSAGES: :[[@LINE-2]]:55: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
+    // CHECK-MESSAGES: :[[@LINE-3]]:70: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
+    // CHECK-FIXES: result2 = static_cast<bool>((value || (flags << 1) || (flags << 2) || (flags << 4)));
+    result2 = static_cast<bool>(((flags << 1) | value | (flags << 2)));
+    // CHECK-MESSAGES: :[[@LINE-1]]:47: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
+    // CHECK-MESSAGES: :[[@LINE-2]]:55: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
+    // CHECK-FIXES: result2 = static_cast<bool>(((flags << 1) || value || (flags << 2)));
+    result2 = static_cast<bool>(((flags << 1) | value | (flags << 2) | (flags << 4)));
+    // CHECK-MESSAGES: :[[@LINE-1]]:47: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
+    // CHECK-MESSAGES: :[[@LINE-2]]:55: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
+    // CHECK-MESSAGES: :[[@LINE-3]]:70: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
+    // CHECK-FIXES: result2 = static_cast<bool>(((flags << 1) || value || (flags << 2) || (flags << 4)));
+    result2 = static_cast<bool>(((flags << 1) | (flags << 2) | value | (flags << 4)));
+    // CHECK-MESSAGES: :[[@LINE-1]]:47: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
+    // CHECK-MESSAGES: :[[@LINE-2]]:62: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
+    // CHECK-MESSAGES: :[[@LINE-3]]:70: warning: use logical operator '||' for boolean semantics instead of bitwise operator '|' [misc-bool-bitwise-operation]
+    // CHECK-FIXES: result2 = static_cast<bool>(((flags << 1) || (flags << 2) || value || (flags << 4)));
 }
 
 

>From bf71aab89f372461e3f85f571ab82dfd8dfd9b2e Mon Sep 17 00:00:00 2001
From: denzor200 <denismikhaylov38 at gmail.com>
Date: Sat, 17 Jan 2026 16:30:28 +0300
Subject: [PATCH 49/49] lint

---
 .../clang-tidy/misc/BoolBitwiseOperationCheck.cpp             | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.cpp b/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.cpp
index ef52e87e043d0..9ac8af1d905f9 100644
--- a/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.cpp
+++ b/clang-tools-extra/clang-tidy/misc/BoolBitwiseOperationCheck.cpp
@@ -88,7 +88,7 @@ AST_MATCHER_P(Expr, hasAllLeavesOfBitwiseSatisfying,
   auto Condition = [&](const clang::Expr *E) -> bool {
     return InnerMatcher.matches(*E, Finder, Builder);
   };
-  return leavesOfBitwiseSatisfy(&Node, Condition, std::logical_and<bool>());
+  return leavesOfBitwiseSatisfy(&Node, Condition, std::logical_and{});
 }
 
 /// Custom matcher that checks if any leaf node in a bitwise expression
@@ -102,7 +102,7 @@ AST_MATCHER_P(Expr, hasAnyLeafOfBitwiseSatisfying,
   auto Condition = [&](const clang::Expr *E) -> bool {
     return InnerMatcher.matches(*E, Finder, Builder);
   };
-  return leavesOfBitwiseSatisfy(&Node, Condition, std::logical_or<bool>());
+  return leavesOfBitwiseSatisfy(&Node, Condition, std::logical_or{});
 }
 } // namespace
 



More information about the cfe-commits mailing list