summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema/SemaExpr.cpp
diff options
context:
space:
mode:
authorDavide Italiano <davide@freebsd.org>2015-07-06 18:02:09 +0000
committerDavide Italiano <davide@freebsd.org>2015-07-06 18:02:09 +0000
commitbf0f7757e24264bb6e211e30f60a75f272b0a90d (patch)
tree7e32d8cc052765a1eea8d89cb7bb42ce4abc0227 /clang/lib/Sema/SemaExpr.cpp
parent183f53fd2213006589847fe40567720296e68717 (diff)
downloadbcm5719-llvm-bf0f7757e24264bb6e211e30f60a75f272b0a90d.tar.gz
bcm5719-llvm-bf0f7757e24264bb6e211e30f60a75f272b0a90d.zip
[Sema] Warn when shifting a negative value.
Example: % ./clang -Wshift-negative-value emit.c emit.c:3:14: warning: shifting a negative signed value is undefined [-Wshift-negative-value] int a = -1 << 3; ~~ ^ 1 warning generated. PR: 24026 Differential Revision: http://reviews.llvm.org/D10938 Reviewed by: rsmith llvm-svn: 241478
Diffstat (limited to 'clang/lib/Sema/SemaExpr.cpp')
-rw-r--r--clang/lib/Sema/SemaExpr.cpp14
1 files changed, 12 insertions, 2 deletions
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index c023c8523a3..01a4d488057 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -7937,9 +7937,19 @@ static void DiagnoseBadShiftValues(Sema& S, ExprResult &LHS, ExprResult &RHS,
// representable in the result type, so never warn for those.
llvm::APSInt Left;
if (LHS.get()->isValueDependent() ||
- !LHS.get()->isIntegerConstantExpr(Left, S.Context) ||
- LHSType->hasUnsignedIntegerRepresentation())
+ LHSType->hasUnsignedIntegerRepresentation() ||
+ !LHS.get()->EvaluateAsInt(Left, S.Context))
return;
+
+ // If LHS does not have a signed type and non-negative value
+ // then, the behavior is undefined. Warn about it.
+ if (Left.isNegative()) {
+ S.DiagRuntimeBehavior(Loc, LHS.get(),
+ S.PDiag(diag::warn_shift_lhs_negative)
+ << LHS.get()->getSourceRange());
+ return;
+ }
+
llvm::APInt ResultBits =
static_cast<llvm::APInt&>(Right) + Left.getMinSignedBits();
if (LeftBits.uge(ResultBits))
OpenPOWER on IntegriCloud