r372612 - [Diagnostics] Warn if '<<' in bool context with -Wint-in-bool-context (GCC compatibility)
David Bolvansky via cfe-commits
cfe-commits at lists.llvm.org
Mon Sep 23 07:21:08 PDT 2019
Author: xbolva00
Date: Mon Sep 23 07:21:08 2019
New Revision: 372612
URL: http://llvm.org/viewvc/llvm-project?rev=372612&view=rev
Log:
[Diagnostics] Warn if '<<' in bool context with -Wint-in-bool-context (GCC compatibility)
Extracted from D63082, addressed review comments related to a warning message.
Added:
cfe/trunk/test/Sema/warn-int-in-bool-context.c
Modified:
cfe/trunk/include/clang/Basic/DiagnosticGroups.td
cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
cfe/trunk/lib/Sema/SemaChecking.cpp
cfe/trunk/test/SemaCXX/cxx2a-explicit-bool.cpp
Modified: cfe/trunk/include/clang/Basic/DiagnosticGroups.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticGroups.td?rev=372612&r1=372611&r2=372612&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticGroups.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticGroups.td Mon Sep 23 07:21:08 2019
@@ -499,6 +499,7 @@ def StringCompare : DiagGroup<"string-co
def StringPlusInt : DiagGroup<"string-plus-int">;
def StringPlusChar : DiagGroup<"string-plus-char">;
def StrncatSize : DiagGroup<"strncat-size">;
+def IntInBoolContext : DiagGroup<"int-in-bool-context">;
def TautologicalTypeLimitCompare : DiagGroup<"tautological-type-limit-compare">;
def TautologicalUnsignedZeroCompare : DiagGroup<"tautological-unsigned-zero-compare">;
def TautologicalUnsignedEnumZeroCompare : DiagGroup<"tautological-unsigned-enum-zero-compare">;
@@ -821,6 +822,7 @@ def Most : DiagGroup<"most", [
Format,
Implicit,
InfiniteRecursion,
+ IntInBoolContext,
MismatchedTags,
MissingBraces,
Move,
Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=372612&r1=372611&r2=372612&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Mon Sep 23 07:21:08 2019
@@ -5720,6 +5720,9 @@ def warn_precedence_conditional : Warnin
def note_precedence_conditional_first : Note<
"place parentheses around the '?:' expression to evaluate it first">;
+def warn_left_shift_in_bool_context : Warning<
+ "converting the result of '<<' to a boolean; did you mean '(%0) != 0'?">,
+ InGroup<IntInBoolContext>;
def warn_logical_instead_of_bitwise : Warning<
"use of logical '%0' with constant operand">,
InGroup<DiagGroup<"constant-logical-operand">>;
Modified: cfe/trunk/lib/Sema/SemaChecking.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaChecking.cpp?rev=372612&r1=372611&r2=372612&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaChecking.cpp (original)
+++ cfe/trunk/lib/Sema/SemaChecking.cpp Mon Sep 23 07:21:08 2019
@@ -11256,10 +11256,16 @@ static bool isSameWidthConstantConversio
return true;
}
-static void DiagnoseIntInBoolContext(Sema &S, const Expr *E) {
+static void DiagnoseIntInBoolContext(Sema &S, Expr *E) {
E = E->IgnoreParenImpCasts();
SourceLocation ExprLoc = E->getExprLoc();
+ if (const auto *BO = dyn_cast<BinaryOperator>(E)) {
+ BinaryOperator::Opcode Opc = BO->getOpcode();
+ if (Opc == BO_Shl)
+ S.Diag(ExprLoc, diag::warn_left_shift_in_bool_context) << E;
+ }
+
if (const auto *CO = dyn_cast<ConditionalOperator>(E)) {
const auto *LHS = dyn_cast<IntegerLiteral>(CO->getTrueExpr());
if (!LHS) {
@@ -11585,6 +11591,9 @@ static void CheckImplicitConversion(Sema
S.DiscardMisalignedMemberAddress(Target, E);
+ if (Target->isBooleanType())
+ DiagnoseIntInBoolContext(S, E);
+
if (!Source->isIntegerType() || !Target->isIntegerType())
return;
Added: cfe/trunk/test/Sema/warn-int-in-bool-context.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/warn-int-in-bool-context.c?rev=372612&view=auto
==============================================================================
--- cfe/trunk/test/Sema/warn-int-in-bool-context.c (added)
+++ cfe/trunk/test/Sema/warn-int-in-bool-context.c Mon Sep 23 07:21:08 2019
@@ -0,0 +1,31 @@
+// RUN: %clang_cc1 -x c -fsyntax-only -verify -Wint-in-bool-context %s
+// RUN: %clang_cc1 -x c -fsyntax-only -verify -Wall %s
+// RUN: %clang_cc1 -x c++ -fsyntax-only -verify -Wint-in-bool-context %s
+// RUN: %clang_cc1 -x c++ -fsyntax-only -verify -Wall %s
+
+#define ONE 1
+#define TWO 2
+
+#define SHIFT(l, r) l << r
+
+#ifdef __cplusplus
+typedef bool boolean;
+#else
+typedef _Bool boolean;
+#endif
+
+int test(int a) {
+ boolean r;
+ r = (1 << 3); // expected-warning {{converting the result of '<<' to a boolean; did you mean '(1 << 3) != 0'?}}
+ r = TWO << 7; // expected-warning {{converting the result of '<<' to a boolean; did you mean '(2 << 7) != 0'?}}
+ r = a << 7; // expected-warning {{converting the result of '<<' to a boolean; did you mean '(a << 7) != 0'?}}
+ r = ONE << a; // expected-warning {{converting the result of '<<' to a boolean; did you mean '(1 << a) != 0'?}}
+ if (TWO << 4) // expected-warning {{converting the result of '<<' to a boolean; did you mean '(2 << 4) != 0'?}}
+ return a;
+
+ if (a << TWO) // expected-warning {{converting the result of '<<' to a boolean; did you mean '(a << 2) != 0'?}}
+ return a;
+
+ // Don't warn in macros.
+ return SHIFT(1, a);
+}
Modified: cfe/trunk/test/SemaCXX/cxx2a-explicit-bool.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/cxx2a-explicit-bool.cpp?rev=372612&r1=372611&r2=372612&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/cxx2a-explicit-bool.cpp (original)
+++ cfe/trunk/test/SemaCXX/cxx2a-explicit-bool.cpp Mon Sep 23 07:21:08 2019
@@ -20,7 +20,7 @@ namespace special_cases
template<int a>
struct A {
// expected-note at -1+ {{candidate constructor}}
- explicit(1 << a)
+ explicit(1 << a) // expected-warning {{converting the result of '<<' to a boolean; did you mean '(1 << -1) != 0'?}}
// expected-note at -1 {{negative shift count -1}}
// expected-error at -2 {{explicit specifier argument is not a constant expression}}
A(int);
More information about the cfe-commits
mailing list