diff options
author | Davide Italiano <davide@freebsd.org> | 2015-07-06 18:02:09 +0000 |
---|---|---|
committer | Davide Italiano <davide@freebsd.org> | 2015-07-06 18:02:09 +0000 |
commit | bf0f7757e24264bb6e211e30f60a75f272b0a90d (patch) | |
tree | 7e32d8cc052765a1eea8d89cb7bb42ce4abc0227 /clang/lib/Sema/SemaExpr.cpp | |
parent | 183f53fd2213006589847fe40567720296e68717 (diff) | |
download | bcm5719-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.cpp | 14 |
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)) |