[PATCH] D141414: [clang] add warning on shifting boolean type
Angelo Matni via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Tue Jan 24 14:48:41 PST 2023
angelomatnigoogle updated this revision to Diff 491923.
angelomatnigoogle added a comment.
Consolidated shift-bool warning; fixed relevant unit tests
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D141414/new/
https://reviews.llvm.org/D141414
Files:
clang/include/clang/Basic/DiagnosticSemaKinds.td
clang/lib/Sema/SemaExpr.cpp
clang/test/AST/Interp/shifts.cpp
clang/test/Analysis/svalbuilder-simplify-no-crash.c
clang/test/CXX/over/over.built/p18.cpp
clang/test/Sema/warn-shift-bool.cpp
Index: clang/test/Sema/warn-shift-bool.cpp
===================================================================
--- /dev/null
+++ clang/test/Sema/warn-shift-bool.cpp
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+int f(int x) {
+ const bool b = 1;
+ const bool c = b << x; // expected-warning {{left shifting 'bool' will implicitly cast to 'int'; consider 'bool && (shift_count | desired_type_width - 1)' to avoid implicitly relying on the width of 'int'}}
+ const bool d = b >> x; // expected-warning {{right shifting 'bool' will implicitly cast to 'int'; consider 'bool & !shift_count' to avoid implicitly relying on the width of 'int'}}
+ return 0;
+}
Index: clang/test/CXX/over/over.built/p18.cpp
===================================================================
--- clang/test/CXX/over/over.built/p18.cpp
+++ clang/test/CXX/over/over.built/p18.cpp
@@ -56,7 +56,7 @@
(void)(i << 3);
(void)(f << 3); // expected-error {{invalid operands}}
- (void)(b << 3);
+ (void)(b << 3); // expected-warning {{left shifting 'bool' will implicitly cast to 'int'; consider 'bool && (shift_count | desired_type_width - 1)' to avoid implicitly relying on the width of 'int'}}
(void)(pi << 3); // expected-error {{invalid operands}}
(void)(pt << 3); // FIXME
(void)(t << 3);
@@ -69,7 +69,7 @@
(void)(i >> 3);
(void)(f >> 3); // expected-error {{invalid operands}}
- (void)(b >> 3);
+ (void)(b >> 3); // expected-warning {{right shifting 'bool' will implicitly cast to 'int'; consider 'bool & !shift_count' to avoid implicitly relying on the width of 'int'}}
(void)(pi >> 3); // expected-error {{invalid operands}}
(void)(pt >> 3); // FIXME
(void)(t >> 3);
Index: clang/test/Analysis/svalbuilder-simplify-no-crash.c
===================================================================
--- clang/test/Analysis/svalbuilder-simplify-no-crash.c
+++ clang/test/Analysis/svalbuilder-simplify-no-crash.c
@@ -9,5 +9,6 @@
void crashing(long a, _Bool b) {
(void)(a & 1 && 0);
b = a & 1;
- (void)(b << 1); // expected-warning{{core.UndefinedBinaryOperatorResult}}
+ (void)(b << 1); // expected-warning{{core.UndefinedBinaryOperatorResult}} \
+ // expected-warning {{left shifting 'bool' will implicitly cast to 'int'; consider 'bool && (shift_count | desired_type_width - 1)' to avoid implicitly relying on the width of 'int'}}
}
Index: clang/test/AST/Interp/shifts.cpp
===================================================================
--- clang/test/AST/Interp/shifts.cpp
+++ clang/test/AST/Interp/shifts.cpp
@@ -109,7 +109,13 @@
static_assert(m == 1, "");
constexpr unsigned char c = 0 << 8;
static_assert(c == 0, "");
- static_assert(true << 1, "");
+
+ constexpr unsigned b = true << 1; // expected-warning {{left shifting 'bool' will implicitly cast to 'int'; consider 'bool && (shift_count | desired_type_width - 1)' to avoid implicitly relying on the width of 'int'}} \
+ // cxx17-warning {{left shifting 'bool' will implicitly cast to 'int'; consider 'bool && (shift_count | desired_type_width - 1)' to avoid implicitly relying on the width of 'int'}} \
+ // ref-warning {{left shifting 'bool' will implicitly cast to 'int'; consider 'bool && (shift_count | desired_type_width - 1)' to avoid implicitly relying on the width of 'int'}} \
+ // ref-cxx17-warning {{left shifting 'bool' will implicitly cast to 'int'; consider 'bool && (shift_count | desired_type_width - 1)' to avoid implicitly relying on the width of 'int'}}
+ static_assert(b, "");
+
static_assert(1 << (__INT_WIDTH__ +1) == 0, ""); // expected-error {{not an integral constant expression}} \
// expected-note {{>= width of type 'int'}} \
// cxx17-error {{not an integral constant expression}} \
Index: clang/lib/Sema/SemaExpr.cpp
===================================================================
--- clang/lib/Sema/SemaExpr.cpp
+++ clang/lib/Sema/SemaExpr.cpp
@@ -11950,6 +11950,10 @@
SourceLocation Loc, BinaryOperatorKind Opc,
bool IsCompAssign) {
checkArithmeticNull(*this, LHS, RHS, Loc, /*IsCompare=*/false);
+ if (LHS.get()->IgnoreParenImpCasts()->getType()->isBooleanType())
+ Diag(Loc, diag::warn_shift_on_bool_type) << (Opc == BO_Shr)
+ << "'bool && (shift_count | desired_type_width - 1)'"
+ << "'bool & !shift_count'";
// Vector shifts promote their scalar inputs to vector type.
if (LHS.get()->getType()->isVectorType() ||
Index: clang/include/clang/Basic/DiagnosticSemaKinds.td
===================================================================
--- clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -6603,6 +6603,9 @@
def warn_shift_result_gt_typewidth : Warning<
"signed shift result (%0) requires %1 bits to represent, but %2 only has "
"%3 bits">, InGroup<DiagGroup<"shift-overflow">>;
+def warn_shift_on_bool_type : Warning<
+ "%select{left|right}0 shifting 'bool' will implicitly cast to 'int'; consider %select{%1|%2}0 "
+ "to avoid implicitly relying on the width of 'int'">, InGroup<DiagGroup<"shift-bool">>;
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">,
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D141414.491923.patch
Type: text/x-patch
Size: 5521 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20230124/db05eea6/attachment-0001.bin>
More information about the cfe-commits
mailing list