[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))