summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--clang/include/clang/Basic/DiagnosticSemaKinds.td4
-rw-r--r--clang/lib/Sema/SemaChecking.cpp47
-rw-r--r--clang/test/Sema/warn-int-in-bool-context.c20
3 files changed, 39 insertions, 32 deletions
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 9e00591c637..e7dacc852b8 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -5722,10 +5722,10 @@ def note_precedence_conditional_first : Note<
def warn_enum_constant_in_bool_context : Warning<
"converting the enum constant to a boolean">,
- InGroup<IntInBoolContext>;
+ InGroup<IntInBoolContext>, DefaultIgnore;
def warn_left_shift_in_bool_context : Warning<
"converting the result of '<<' to a boolean; did you mean '(%0) != 0'?">,
- InGroup<IntInBoolContext>;
+ InGroup<IntInBoolContext>, DefaultIgnore;
def warn_logical_instead_of_bitwise : Warning<
"use of logical '%0' with constant operand">,
InGroup<DiagGroup<"constant-logical-operand">>;
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index 19c83d6bac2..59b875aed76 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -11296,44 +11296,39 @@ static bool isSameWidthConstantConversion(Sema &S, Expr *E, QualType T,
return true;
}
+static const IntegerLiteral *getIntegerLiteral(Expr *E) {
+ const auto *IL = dyn_cast<IntegerLiteral>(E);
+ if (!IL) {
+ if (auto *UO = dyn_cast<UnaryOperator>(E)) {
+ if (UO->getOpcode() == UO_Minus)
+ return dyn_cast<IntegerLiteral>(UO->getSubExpr());
+ }
+ }
+
+ return IL;
+}
+
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)
+ // Do not diagnose unsigned shifts.
+ if (Opc == BO_Shl && E->getType()->isSignedIntegerType())
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) {
- if (auto *UO = dyn_cast<UnaryOperator>(CO->getTrueExpr())) {
- if (UO->getOpcode() == UO_Minus)
- LHS = dyn_cast<IntegerLiteral>(UO->getSubExpr());
- if (!LHS)
- return;
- } else {
- return;
- }
- }
-
- const auto *RHS = dyn_cast<IntegerLiteral>(CO->getFalseExpr());
- if (!RHS) {
- if (auto *UO = dyn_cast<UnaryOperator>(CO->getFalseExpr())) {
- if (UO->getOpcode() == UO_Minus)
- RHS = dyn_cast<IntegerLiteral>(UO->getSubExpr());
- if (!RHS)
- return;
- } else {
- return;
- }
- }
-
+ const auto *LHS = getIntegerLiteral(CO->getTrueExpr());
+ if (!LHS)
+ return;
+ const auto *RHS = getIntegerLiteral(CO->getFalseExpr());
+ if (!RHS)
+ return;
if ((LHS->getValue() == 0 || LHS->getValue() == 1) &&
(RHS->getValue() == 0 || RHS->getValue() == 1))
- // Do not diagnose common idioms
+ // Do not diagnose common idioms.
return;
if (LHS->getValue() != 0 && LHS->getValue() != 0)
S.Diag(ExprLoc, diag::warn_integer_constants_in_conditional_always_true);
diff --git a/clang/test/Sema/warn-int-in-bool-context.c b/clang/test/Sema/warn-int-in-bool-context.c
index f190fdf6a1d..ae35ca34fbb 100644
--- a/clang/test/Sema/warn-int-in-bool-context.c
+++ b/clang/test/Sema/warn-int-in-bool-context.c
@@ -7,6 +7,8 @@
#define TWO 2
#define SHIFT(l, r) l << r
+#define MM a << a
+#define AF 1 << 7
#ifdef __cplusplus
typedef bool boolean;
@@ -20,15 +22,25 @@ enum num {
two,
};
-int test(int a, enum num n) {
+int test(int a, unsigned b, enum num n) {
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 << a; // expected-warning {{converting the result of '<<' to a boolean; did you mean '(a << a) != 0'?}}
+ r = MM; // expected-warning {{converting the result of '<<' to a boolean; did you mean '(a << a) != 0'?}}
+ r = (1 << 7); // expected-warning {{converting the result of '<<' to a boolean; did you mean '(1 << 7) != 0'?}}
+ r = 2UL << 2;
+ r = 2 << b; // expected-warning {{converting the result of '<<' to a boolean; did you mean '(2 << b) != 0'?}}
+ r = (unsigned)(2 << b);
+ r = b << 7;
+ r = (1 << a); // expected-warning {{converting the result of '<<' to a boolean; did you mean '(1 << a) != 0'?}}
+ r = TWO << a; // expected-warning {{converting the result of '<<' to a boolean; did you mean '(2 << a) != 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'?}}
+ if (TWO << a) // expected-warning {{converting the result of '<<' to a boolean; did you mean '(2 << a) != 0'?}}
return a;
+ for (a = 0; 1 << a; a++) // expected-warning {{converting the result of '<<' to a boolean; did you mean '(1 << a) != 0'?}}
+ ;
+
if (a << TWO) // expected-warning {{converting the result of '<<' to a boolean; did you mean '(a << 2) != 0'?}}
return a;
OpenPOWER on IntegriCloud