r296214 - [ubsan] Detect signed overflow UB in remainder operations

Vedant Kumar via cfe-commits cfe-commits at lists.llvm.org
Fri Feb 24 16:43:40 PST 2017


Author: vedantk
Date: Fri Feb 24 18:43:39 2017
New Revision: 296214

URL: http://llvm.org/viewvc/llvm-project?rev=296214&view=rev
Log:
[ubsan] Detect signed overflow UB in remainder operations

Teach ubsan to diagnose remainder operations which have undefined
behavior due to signed overflow (e.g INT_MIN % -1).

Differential Revision: https://reviews.llvm.org/D29437

Modified:
    cfe/trunk/lib/CodeGen/CGExprScalar.cpp
    cfe/trunk/test/CodeGen/ubsan-promoted-arith.cpp

Modified: cfe/trunk/lib/CodeGen/CGExprScalar.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprScalar.cpp?rev=296214&r1=296213&r2=296214&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGExprScalar.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExprScalar.cpp Fri Feb 24 18:43:39 2017
@@ -2403,12 +2403,12 @@ Value *ScalarExprEmitter::EmitDiv(const
 
 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())

Modified: cfe/trunk/test/CodeGen/ubsan-promoted-arith.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/ubsan-promoted-arith.cpp?rev=296214&r1=296213&r2=296214&view=diff
==============================================================================
--- cfe/trunk/test/CodeGen/ubsan-promoted-arith.cpp (original)
+++ cfe/trunk/test/CodeGen/ubsan-promoted-arith.cpp Fri Feb 24 18:43:39 2017
@@ -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; }




More information about the cfe-commits mailing list