summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--clang/lib/CodeGen/CGExprScalar.cpp8
-rw-r--r--clang/test/CodeGen/ubsan-promoted-arith.cpp13
2 files changed, 14 insertions, 7 deletions
diff --git a/clang/lib/CodeGen/CGExprScalar.cpp b/clang/lib/CodeGen/CGExprScalar.cpp
index c14e6d12da8..529642cb83e 100644
--- a/clang/lib/CodeGen/CGExprScalar.cpp
+++ b/clang/lib/CodeGen/CGExprScalar.cpp
@@ -2403,12 +2403,12 @@ Value *ScalarExprEmitter::EmitDiv(const BinOpInfo &Ops) {
Value *ScalarExprEmitter::EmitRem(const BinOpInfo &Ops) {
// Rem in C can't be a floating point type: C99 6.5.5p2.
- if (CGF.SanOpts.has(SanitizerKind::IntegerDivideByZero)) {
+ if ((CGF.SanOpts.has(SanitizerKind::IntegerDivideByZero) ||
+ CGF.SanOpts.has(SanitizerKind::SignedIntegerOverflow)) &&
+ Ops.Ty->isIntegerType()) {
CodeGenFunction::SanitizerScope SanScope(&CGF);
llvm::Value *Zero = llvm::Constant::getNullValue(ConvertType(Ops.Ty));
-
- if (Ops.Ty->isIntegerType())
- EmitUndefinedBehaviorIntegerDivAndRemCheck(Ops, Zero, false);
+ EmitUndefinedBehaviorIntegerDivAndRemCheck(Ops, Zero, false);
}
if (Ops.Ty->hasUnsignedIntegerRepresentation())
diff --git a/clang/test/CodeGen/ubsan-promoted-arith.cpp b/clang/test/CodeGen/ubsan-promoted-arith.cpp
index 19cbc0ebdab..5a2898b5423 100644
--- a/clang/test/CodeGen/ubsan-promoted-arith.cpp
+++ b/clang/test/CodeGen/ubsan-promoted-arith.cpp
@@ -2,6 +2,7 @@
typedef unsigned char uchar;
typedef unsigned short ushort;
+typedef int int4 __attribute__((ext_vector_type(4)));
enum E1 : int {
a
@@ -101,12 +102,14 @@ char rem1(char c) { return c % c; }
// CHECK-NOT: ubsan_handle_divrem_overflow
uchar rem2(uchar uc) { return uc % uc; }
-// FIXME: This is a long-standing false negative.
-//
// CHECK-LABEL: define signext i8 @_Z4rem3
-// rdar30301609: ubsan_handle_divrem_overflow
+// CHECK: ubsan_handle_divrem_overflow
char rem3(int i, char c) { return i % c; }
+// CHECK-LABEL: define signext i8 @_Z4rem4
+// CHECK-NOT: ubsan_handle_divrem_overflow
+char rem4(char c, int i) { return c % i; }
+
// CHECK-LABEL: define signext i8 @_Z4inc1
// CHECK-NOT: sadd.with.overflow
char inc1(char c) { return c++ + (char)0; }
@@ -122,3 +125,7 @@ void inc3(char c) { c++; }
// CHECK-LABEL: define void @_Z4inc4
// CHECK-NOT: uadd.with.overflow
void inc4(uchar uc) { uc++; }
+
+// CHECK-LABEL: define <4 x i32> @_Z4vremDv4_iS_
+// CHECK-NOT: ubsan_handle_divrem_overflow
+int4 vrem(int4 a, int4 b) { return a % b; }
OpenPOWER on IntegriCloud