aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen/CGExprScalar.cpp
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2012-11-06 02:30:30 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2012-11-06 02:30:30 +0000
commitc54e25f9450d927dcd41270639523c1b4c0d5868 (patch)
treec6db1b9a7e9b51da3fa7c7d023216774d0e3b202 /lib/CodeGen/CGExprScalar.cpp
parentfc1b1bbb5bef02a48a131da72567e3ab869f9db3 (diff)
Classify the INT_MIN/-1 check as -fsanitize=signed-integer-overflow, not as -fsanitize=divide-by-zero.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@167433 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/CGExprScalar.cpp')
-rw-r--r--lib/CodeGen/CGExprScalar.cpp26
1 files changed, 17 insertions, 9 deletions
diff --git a/lib/CodeGen/CGExprScalar.cpp b/lib/CodeGen/CGExprScalar.cpp
index c21cbf6773..b429b1d6e4 100644
--- a/lib/CodeGen/CGExprScalar.cpp
+++ b/lib/CodeGen/CGExprScalar.cpp
@@ -1924,30 +1924,38 @@ Value *ScalarExprEmitter::EmitCompoundAssign(const CompoundAssignOperator *E,
void ScalarExprEmitter::EmitUndefinedBehaviorIntegerDivAndRemCheck(
const BinOpInfo &Ops, llvm::Value *Zero, bool isDiv) {
- llvm::IntegerType *Ty = cast<llvm::IntegerType>(Zero->getType());
+ llvm::Value *Cond = 0;
+
+ if (CGF.getLangOpts().SanitizeDivideByZero)
+ Cond = Builder.CreateICmpNE(Ops.RHS, Zero);
+
+ if (CGF.getLangOpts().SanitizeSignedIntegerOverflow &&
+ Ops.Ty->hasSignedIntegerRepresentation()) {
+ llvm::IntegerType *Ty = cast<llvm::IntegerType>(Zero->getType());
- if (Ops.Ty->hasSignedIntegerRepresentation()) {
llvm::Value *IntMin =
Builder.getInt(llvm::APInt::getSignedMinValue(Ty->getBitWidth()));
llvm::Value *NegOne = llvm::ConstantInt::get(Ty, -1ULL);
- llvm::Value *Cond1 = Builder.CreateICmpNE(Ops.RHS, Zero);
llvm::Value *LHSCmp = Builder.CreateICmpNE(Ops.LHS, IntMin);
llvm::Value *RHSCmp = Builder.CreateICmpNE(Ops.RHS, NegOne);
- llvm::Value *Cond2 = Builder.CreateOr(LHSCmp, RHSCmp, "or");
- EmitBinOpCheck(Builder.CreateAnd(Cond1, Cond2, "and"), Ops);
- } else {
- EmitBinOpCheck(Builder.CreateICmpNE(Ops.RHS, Zero), Ops);
+ llvm::Value *Overflow = Builder.CreateOr(LHSCmp, RHSCmp, "or");
+ Cond = Cond ? Builder.CreateAnd(Cond, Overflow, "and") : Overflow;
}
+
+ if (Cond)
+ EmitBinOpCheck(Cond, Ops);
}
Value *ScalarExprEmitter::EmitDiv(const BinOpInfo &Ops) {
- if (CGF.getLangOpts().SanitizeDivideByZero) {
+ if (CGF.getLangOpts().SanitizeDivideByZero ||
+ CGF.getLangOpts().SanitizeSignedIntegerOverflow) {
llvm::Value *Zero = llvm::Constant::getNullValue(ConvertType(Ops.Ty));
if (Ops.Ty->isIntegerType())
EmitUndefinedBehaviorIntegerDivAndRemCheck(Ops, Zero, true);
- else if (Ops.Ty->isRealFloatingType())
+ else if (CGF.getLangOpts().SanitizeDivideByZero &&
+ Ops.Ty->isRealFloatingType())
EmitBinOpCheck(Builder.CreateFCmpUNE(Ops.RHS, Zero), Ops);
}
if (Ops.LHS->getType()->isFPOrFPVectorTy()) {