r372749 - [Diagnostics] Handle tautological left shifts in boolean context
David Bolvansky via cfe-commits
cfe-commits at lists.llvm.org
Tue Sep 24 06:14:18 PDT 2019
Author: xbolva00
Date: Tue Sep 24 06:14:18 2019
New Revision: 372749
URL: http://llvm.org/viewvc/llvm-project?rev=372749&view=rev
Log:
[Diagnostics] Handle tautological left shifts in boolean context
Modified:
cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
cfe/trunk/lib/Sema/SemaChecking.cpp
cfe/trunk/test/Sema/warn-int-in-bool-context.c
Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=372749&r1=372748&r2=372749&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Tue Sep 24 06:14:18 2019
@@ -6155,6 +6155,10 @@ def warn_integer_constants_in_conditiona
"converting the result of '?:' with integer constants to a boolean always "
"evaluates to 'true'">,
InGroup<TautologicalConstantCompare>;
+def warn_left_shift_always : Warning<
+ "converting the result of '<<' to a boolean always evaluates "
+ "to %select{false|true}0">,
+ InGroup<TautologicalConstantCompare>;
def warn_comparison_of_mixed_enum_types : Warning<
"comparison of two values with different enumeration types"
"%diff{ ($ and $)|}0,1">,
Modified: cfe/trunk/lib/Sema/SemaChecking.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaChecking.cpp?rev=372749&r1=372748&r2=372749&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaChecking.cpp (original)
+++ cfe/trunk/lib/Sema/SemaChecking.cpp Tue Sep 24 06:14:18 2019
@@ -11314,17 +11314,26 @@ static void DiagnoseIntInBoolContext(Sem
if (const auto *BO = dyn_cast<BinaryOperator>(E)) {
BinaryOperator::Opcode Opc = BO->getOpcode();
+ Expr::EvalResult Result;
// Do not diagnose unsigned shifts.
- if (Opc == BO_Shl && E->getType()->isSignedIntegerType())
- S.Diag(ExprLoc, diag::warn_left_shift_in_bool_context) << E;
+ if (Opc == BO_Shl) {
+ const auto *LHS = getIntegerLiteral(BO->getLHS());
+ const auto *RHS = getIntegerLiteral(BO->getRHS());
+ if (LHS && LHS->getValue() == 0)
+ S.Diag(ExprLoc, diag::warn_left_shift_always) << 0;
+ else if (RHS && RHS->getValue().isNonNegative() &&
+ E->EvaluateAsInt(Result, S.Context, Expr::SE_AllowSideEffects))
+ S.Diag(ExprLoc, diag::warn_left_shift_always)
+ << (Result.Val.getInt() != 0);
+ else if (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 = getIntegerLiteral(CO->getTrueExpr());
- if (!LHS)
- return;
const auto *RHS = getIntegerLiteral(CO->getFalseExpr());
- if (!RHS)
+ if (!LHS || !RHS)
return;
if ((LHS->getValue() == 0 || LHS->getValue() == 1) &&
(RHS->getValue() == 0 || RHS->getValue() == 1))
Modified: 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=372749&r1=372748&r2=372749&view=diff
==============================================================================
--- cfe/trunk/test/Sema/warn-int-in-bool-context.c (original)
+++ cfe/trunk/test/Sema/warn-int-in-bool-context.c Tue Sep 24 06:14:18 2019
@@ -24,12 +24,17 @@ enum num {
int test(int a, unsigned b, enum num n) {
boolean r;
- 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 = 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 always evaluates to true}}
+ r = 2UL << 2; // expected-warning {{converting the result of '<<' to a boolean always evaluates to true}}
+ r = 0 << a; // expected-warning {{converting the result of '<<' to a boolean always evaluates to false}}
+ r = 0 << 2; // expected-warning {{converting the result of '<<' to a boolean always evaluates to false}}
+ r = 1 << 0; // expected-warning {{converting the result of '<<' to a boolean always evaluates to true}}
+ r = 1 << 2; // expected-warning {{converting the result of '<<' to a boolean always evaluates to true}}
+ r = 1ULL << 2; // expected-warning {{converting the result of '<<' to a boolean always evaluates to true}}
+ 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'?}}
@@ -39,7 +44,7 @@ int test(int a, unsigned b, enum num n)
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;
More information about the cfe-commits
mailing list