PR3333: warn when shifting by invalid amount

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@78385 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp
index 7ef30d3..51ebd07 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -4124,6 +4124,29 @@
 
   UsualUnaryConversions(rex);
 
+  // Sanity-check shift operands
+  llvm::APSInt Right;
+  // Check right/shifter operand
+  if (rex->isIntegerConstantExpr(Right, Context)) {
+    // Check left/shiftee operand
+    llvm::APSInt Left;
+    if (lex->isIntegerConstantExpr(Left, Context)) {
+      if (Left == 0 && Right != 0)
+        Diag(Loc, diag::warn_op_no_effect)
+          << lex->getSourceRange() << rex->getSourceRange();
+    }
+    if (isCompAssign && Right == 0)
+      Diag(Loc, diag::warn_op_no_effect) << rex->getSourceRange();
+    else if (Right.isNegative())
+      Diag(Loc, diag::warn_shift_negative) << rex->getSourceRange();
+    else {
+      llvm::APInt LeftBits(Right.getBitWidth(),
+                          Context.getTypeSize(lex->getType()));
+      if (Right.uge(LeftBits))
+        Diag(Loc, diag::warn_shift_gt_typewidth) << rex->getSourceRange();
+    }
+  }
+
   // "The type of the result is that of the promoted left operand."
   return LHSTy;
 }