forked from OSchip/llvm-project
[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 llvm-svn: 296214
This commit is contained in:
parent
82ee16beb8
commit
42de380765
|
@ -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())
|
||||
|
|
|
@ -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; }
|
||||
|
|
Loading…
Reference in New Issue