[Diagnostics] Handle tautological left shifts in boolean context
llvm-svn: 372749
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index 59b875a..02c0d48 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -11314,17 +11314,26 @@
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))