[cfe-commits] r167433 - in /cfe/trunk: lib/CodeGen/CGExprScalar.cpp test/CodeGen/catch-undef-behavior.c
Richard Smith
richard-llvm at metafoo.co.uk
Mon Nov 5 18:30:30 PST 2012
Author: rsmith
Date: Mon Nov 5 20:30:30 2012
New Revision: 167433
URL: http://llvm.org/viewvc/llvm-project?rev=167433&view=rev
Log:
Classify the INT_MIN/-1 check as -fsanitize=signed-integer-overflow, not as -fsanitize=divide-by-zero.
Modified:
cfe/trunk/lib/CodeGen/CGExprScalar.cpp
cfe/trunk/test/CodeGen/catch-undef-behavior.c
Modified: cfe/trunk/lib/CodeGen/CGExprScalar.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprScalar.cpp?rev=167433&r1=167432&r2=167433&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGExprScalar.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExprScalar.cpp Mon Nov 5 20:30:30 2012
@@ -1924,30 +1924,38 @@
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()) {
Modified: cfe/trunk/test/CodeGen/catch-undef-behavior.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/catch-undef-behavior.c?rev=167433&r1=167432&r2=167433&view=diff
==============================================================================
--- cfe/trunk/test/CodeGen/catch-undef-behavior.c (original)
+++ cfe/trunk/test/CodeGen/catch-undef-behavior.c Mon Nov 5 20:30:30 2012
@@ -1,5 +1,6 @@
-// RUN: %clang_cc1 -fsanitize=alignment,null,object-size,shift,return,signed-integer-overflow,vla-bound,float-cast-overflow -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s
+// RUN: %clang_cc1 -fsanitize=alignment,null,object-size,shift,return,signed-integer-overflow,vla-bound,float-cast-overflow,divide-by-zero -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s
// RUN: %clang_cc1 -fsanitize=null -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s --check-prefix=CHECK-NULL
+// RUN: %clang_cc1 -fsanitize=signed-integer-overflow -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s --check-prefix=CHECK-OVERFLOW
// CHECK: @[[INT:.*]] = private unnamed_addr constant { i16, i16, [6 x i8] } { i16 0, i16 11, [6 x i8] c"'int'\00" }
@@ -221,3 +222,27 @@
// CHECK: call void @__ubsan_handle_float_cast_overflow(
return f;
}
+
+// CHECK: @int_divide_overflow
+// CHECK-OVERFLOW: @int_divide_overflow
+int int_divide_overflow(int a, int b) {
+ // CHECK: %[[ZERO:.*]] = icmp ne i32 %[[B:.*]], 0
+ // CHECK-OVERFLOW-NOT: icmp ne i32 %{{.*}}, 0
+
+ // CHECK: %[[AOK:.*]] = icmp ne i32 %[[A:.*]], -2147483648
+ // CHECK-NEXT: %[[BOK:.*]] = icmp ne i32 %[[B]], -1
+ // CHECK-NEXT: %[[OVER:.*]] = or i1 %[[AOK]], %[[BOK]]
+
+ // CHECK-OVERFLOW: %[[AOK:.*]] = icmp ne i32 %[[A:.*]], -2147483648
+ // CHECK-OVERFLOW-NEXT: %[[BOK:.*]] = icmp ne i32 %[[B:.*]], -1
+ // CHECK-OVERFLOW-NEXT: %[[OK:.*]] = or i1 %[[AOK]], %[[BOK]]
+
+ // CHECK: %[[OK:.*]] = and i1 %[[ZERO]], %[[OVER]]
+
+ // CHECK: br i1 %[[OK]]
+ // CHECK-OVERFLOW: br i1 %[[OK]]
+ return a / b;
+
+ // CHECK: }
+ // CHECK-OVERFLOW: }
+}
More information about the cfe-commits
mailing list