diff options
author | Will Dietz <wdietz2@illinois.edu> | 2012-11-27 15:01:55 +0000 |
---|---|---|
committer | Will Dietz <wdietz2@illinois.edu> | 2012-11-27 15:01:55 +0000 |
commit | b85403658a77e9c19c391c8f02bc7767544a25d9 (patch) | |
tree | d62d664df13c62a47365c673a7d30982d6f44ca1 /test/CodeGen/unsigned-overflow.c | |
parent | 5e7b43ed3071a98d68b6da4f22720b9076d6f18a (diff) |
Add -fsanitize=integer for reporting suspicious integer behaviors.
Introduces new sanitizer "unsigned-integer-overflow".
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@168701 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'test/CodeGen/unsigned-overflow.c')
-rw-r--r-- | test/CodeGen/unsigned-overflow.c | 125 |
1 files changed, 125 insertions, 0 deletions
diff --git a/test/CodeGen/unsigned-overflow.c b/test/CodeGen/unsigned-overflow.c new file mode 100644 index 0000000000..341ea35563 --- /dev/null +++ b/test/CodeGen/unsigned-overflow.c @@ -0,0 +1,125 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsanitize=unsigned-integer-overflow %s -emit-llvm -o - | FileCheck %s +// Verify checked operations are emitted for integers and longs. +// unsigned short/char's tested in unsigned-promotion.c + +unsigned long li, lj, lk; +unsigned int ii, ij, ik; + +extern void opaquelong(unsigned long); +extern void opaqueint(unsigned int); + +// CHECK: define void @testlongadd() +void testlongadd() { + + // CHECK: [[T1:%.*]] = load i64* @lj + // CHECK-NEXT: [[T2:%.*]] = load i64* @lk + // CHECK-NEXT: [[T3:%.*]] = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 [[T1]], i64 [[T2]]) + // CHECK-NEXT: [[T4:%.*]] = extractvalue { i64, i1 } [[T3]], 0 + // CHECK-NEXT: [[T5:%.*]] = extractvalue { i64, i1 } [[T3]], 1 + // CHECK: call void @__ubsan_handle_add_overflow + li = lj + lk; +} + +// CHECK: define void @testlongsub() +void testlongsub() { + + // CHECK: [[T1:%.*]] = load i64* @lj + // CHECK-NEXT: [[T2:%.*]] = load i64* @lk + // CHECK-NEXT: [[T3:%.*]] = call { i64, i1 } @llvm.usub.with.overflow.i64(i64 [[T1]], i64 [[T2]]) + // CHECK-NEXT: [[T4:%.*]] = extractvalue { i64, i1 } [[T3]], 0 + // CHECK-NEXT: [[T5:%.*]] = extractvalue { i64, i1 } [[T3]], 1 + // CHECK: call void @__ubsan_handle_sub_overflow + li = lj - lk; +} + +// CHECK: define void @testlongmul() +void testlongmul() { + + // CHECK: [[T1:%.*]] = load i64* @lj + // CHECK-NEXT: [[T2:%.*]] = load i64* @lk + // CHECK-NEXT: [[T3:%.*]] = call { i64, i1 } @llvm.umul.with.overflow.i64(i64 [[T1]], i64 [[T2]]) + // CHECK-NEXT: [[T4:%.*]] = extractvalue { i64, i1 } [[T3]], 0 + // CHECK-NEXT: [[T5:%.*]] = extractvalue { i64, i1 } [[T3]], 1 + // CHECK: call void @__ubsan_handle_mul_overflow + li = lj * lk; +} + +// CHECK: define void @testlongpostinc() +void testlongpostinc() { + opaquelong(li++); + + // CHECK: [[T1:%.*]] = load i64* @li + // CHECK-NEXT: [[T2:%.*]] = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 [[T1]], i64 1) + // CHECK-NEXT: [[T3:%.*]] = extractvalue { i64, i1 } [[T2]], 0 + // CHECK-NEXT: [[T4:%.*]] = extractvalue { i64, i1 } [[T2]], 1 + // CHECK: call void @__ubsan_handle_add_overflow +} + +// CHECK: define void @testlongpreinc() +void testlongpreinc() { + opaquelong(++li); + + // CHECK: [[T1:%.*]] = load i64* @li + // CHECK-NEXT: [[T2:%.*]] = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 [[T1]], i64 1) + // CHECK-NEXT: [[T3:%.*]] = extractvalue { i64, i1 } [[T2]], 0 + // CHECK-NEXT: [[T4:%.*]] = extractvalue { i64, i1 } [[T2]], 1 + // CHECK: call void @__ubsan_handle_add_overflow +} + +// CHECK: define void @testintadd() +void testintadd() { + + // CHECK: [[T1:%.*]] = load i32* @ij + // CHECK-NEXT: [[T2:%.*]] = load i32* @ik + // CHECK-NEXT: [[T3:%.*]] = call { i32, i1 } @llvm.uadd.with.overflow.i32(i32 [[T1]], i32 [[T2]]) + // CHECK-NEXT: [[T4:%.*]] = extractvalue { i32, i1 } [[T3]], 0 + // CHECK-NEXT: [[T5:%.*]] = extractvalue { i32, i1 } [[T3]], 1 + // CHECK: call void @__ubsan_handle_add_overflow + ii = ij + ik; +} + +// CHECK: define void @testintsub() +void testintsub() { + + // CHECK: [[T1:%.*]] = load i32* @ij + // CHECK-NEXT: [[T2:%.*]] = load i32* @ik + // CHECK-NEXT: [[T3:%.*]] = call { i32, i1 } @llvm.usub.with.overflow.i32(i32 [[T1]], i32 [[T2]]) + // CHECK-NEXT: [[T4:%.*]] = extractvalue { i32, i1 } [[T3]], 0 + // CHECK-NEXT: [[T5:%.*]] = extractvalue { i32, i1 } [[T3]], 1 + // CHECK: call void @__ubsan_handle_sub_overflow + ii = ij - ik; +} + +// CHECK: define void @testintmul() +void testintmul() { + + // CHECK: [[T1:%.*]] = load i32* @ij + // CHECK-NEXT: [[T2:%.*]] = load i32* @ik + // CHECK-NEXT: [[T3:%.*]] = call { i32, i1 } @llvm.umul.with.overflow.i32(i32 [[T1]], i32 [[T2]]) + // CHECK-NEXT: [[T4:%.*]] = extractvalue { i32, i1 } [[T3]], 0 + // CHECK-NEXT: [[T5:%.*]] = extractvalue { i32, i1 } [[T3]], 1 + // CHECK: call void @__ubsan_handle_mul_overflow + ii = ij * ik; +} + +// CHECK: define void @testintpostinc() +void testintpostinc() { + opaqueint(ii++); + + // CHECK: [[T1:%.*]] = load i32* @ii + // CHECK-NEXT: [[T2:%.*]] = call { i32, i1 } @llvm.uadd.with.overflow.i32(i32 [[T1]], i32 1) + // CHECK-NEXT: [[T3:%.*]] = extractvalue { i32, i1 } [[T2]], 0 + // CHECK-NEXT: [[T4:%.*]] = extractvalue { i32, i1 } [[T2]], 1 + // CHECK: call void @__ubsan_handle_add_overflow +} + +// CHECK: define void @testintpreinc() +void testintpreinc() { + opaqueint(++ii); + + // CHECK: [[T1:%.*]] = load i32* @ii + // CHECK-NEXT: [[T2:%.*]] = call { i32, i1 } @llvm.uadd.with.overflow.i32(i32 [[T1]], i32 1) + // CHECK-NEXT: [[T3:%.*]] = extractvalue { i32, i1 } [[T2]], 0 + // CHECK-NEXT: [[T4:%.*]] = extractvalue { i32, i1 } [[T2]], 1 + // CHECK: call void @__ubsan_handle_add_overflow +} |