[clang] 93f0f3d - [Clang] add -Wshift-bool warning to handle shifting of bool (#127336)

via cfe-commits cfe-commits at lists.llvm.org
Thu Mar 6 15:05:59 PST 2025


Author: Oleksandr T.
Date: 2025-03-07T01:05:56+02:00
New Revision: 93f0f3d33be596321730e9194cf24a73a75ce702

URL: https://github.com/llvm/llvm-project/commit/93f0f3d33be596321730e9194cf24a73a75ce702
DIFF: https://github.com/llvm/llvm-project/commit/93f0f3d33be596321730e9194cf24a73a75ce702.diff

LOG: [Clang] add -Wshift-bool warning to handle shifting of bool (#127336)

Fixes #28334

--- 

This PR introduces the `-Wshift-bool` warning to detect and warn against
shifting `bool` values using the `>>` operator. Shifting a `bool`
implicitly converts it to an `int`, which can lead to unintended
behavior.

Added: 
    clang/test/Sema/shift-bool.cpp

Modified: 
    clang/docs/ReleaseNotes.rst
    clang/include/clang/Basic/DiagnosticSemaKinds.td
    clang/lib/Sema/SemaExpr.cpp

Removed: 
    


################################################################################
diff  --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 38b5bdf1dd46b..e1a8dad87ad29 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -222,6 +222,7 @@ Improvements to Clang's diagnostics
   under the subgroup ``-Wunsafe-buffer-usage-in-libc-call``.
 - Diagnostics on chained comparisons (``a < b < c``) are now an error by default. This can be disabled with
   ``-Wno-error=parentheses``.
+- The ``-Wshift-bool`` warning has been added to warn about shifting a boolean. (#GH28334)
 
 - The :doc:`ThreadSafetyAnalysis` now supports ``-Wthread-safety-pointer``,
   which enables warning on passing or returning pointers to guarded variables

diff  --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 5e73c357a8124..cf0e9846d4259 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -7132,6 +7132,9 @@ def warn_shift_result_sets_sign_bit : Warning<
   "signed shift result (%0) sets the sign bit of the shift expression's "
   "type (%1) and becomes negative">,
   InGroup<DiagGroup<"shift-sign-overflow">>, DefaultIgnore;
+def warn_shift_bool : Warning<
+  "right shifting a 'bool' implicitly converts it to 'int'">,
+  InGroup<DiagGroup<"shift-bool">>, DefaultIgnore;
 
 def warn_precedence_bitwise_rel : Warning<
   "%0 has lower precedence than %1; %1 will be evaluated first">,

diff  --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 7904ba966b38d..f896ccab53a54 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -11247,6 +11247,10 @@ static void DiagnoseBadShiftValues(Sema& S, ExprResult &LHS, ExprResult &RHS,
   if (S.getLangOpts().OpenCL)
     return;
 
+  if (Opc == BO_Shr &&
+      LHS.get()->IgnoreParenImpCasts()->getType()->isBooleanType())
+    S.Diag(Loc, diag::warn_shift_bool) << LHS.get()->getSourceRange();
+
   // Check right/shifter operand
   Expr::EvalResult RHSResult;
   if (RHS.get()->isValueDependent() ||

diff  --git a/clang/test/Sema/shift-bool.cpp b/clang/test/Sema/shift-bool.cpp
new file mode 100644
index 0000000000000..a17a0e0ad9e7d
--- /dev/null
+++ b/clang/test/Sema/shift-bool.cpp
@@ -0,0 +1,25 @@
+// RUN: %clang_cc1 -fsyntax-only -Wshift-bool -verify %s
+
+void t() {
+  int x = 10;
+  bool y = true;
+
+  bool a = y << x;
+  bool b = y >> x; // expected-warning {{right shifting a 'bool' implicitly converts it to 'int'}}
+
+  bool c = false << x;
+  bool d = false >> x; // expected-warning {{right shifting a 'bool' implicitly converts it to 'int'}}
+
+  bool e = y << 1;
+  bool f = y >> 1; // expected-warning {{right shifting a 'bool' implicitly converts it to 'int'}}
+
+  bool g = y << -1; // expected-warning {{shift count is negative}}
+  bool h = y >> -1; // expected-warning {{right shifting a 'bool' implicitly converts it to 'int'}} \
+                    // expected-warning {{shift count is negative}}
+
+  bool i = y << 0;
+  bool j = y >> 0; // expected-warning {{right shifting a 'bool' implicitly converts it to 'int'}}
+
+  if ((y << 1) != 0) { }
+  if ((y >> 1) != 0) { } // expected-warning {{right shifting a 'bool' implicitly converts it to 'int'}}
+}


        


More information about the cfe-commits mailing list