1 // RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsanitize=unsigned-integer-overflow %s -emit-llvm -o - | FileCheck %s 2 // Verify checked operations are emitted for integers and longs. 3 // unsigned short/char's tested in unsigned-promotion.c 4 5 unsigned long li, lj, lk; 6 unsigned int ii, ij, ik; 7 8 extern void opaquelong(unsigned long); 9 extern void opaqueint(unsigned int); 10 11 // CHECK-LABEL: define void @testlongadd() 12 void testlongadd() { 13 14 // CHECK: [[T1:%.*]] = load i64* @lj 15 // CHECK-NEXT: [[T2:%.*]] = load i64* @lk 16 // CHECK-NEXT: [[T3:%.*]] = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 [[T1]], i64 [[T2]]) 17 // CHECK-NEXT: [[T4:%.*]] = extractvalue { i64, i1 } [[T3]], 0 18 // CHECK-NEXT: [[T5:%.*]] = extractvalue { i64, i1 } [[T3]], 1 19 // CHECK: call void @__ubsan_handle_add_overflow 20 li = lj + lk; 21 } 22 23 // CHECK-LABEL: define void @testlongsub() 24 void testlongsub() { 25 26 // CHECK: [[T1:%.*]] = load i64* @lj 27 // CHECK-NEXT: [[T2:%.*]] = load i64* @lk 28 // CHECK-NEXT: [[T3:%.*]] = call { i64, i1 } @llvm.usub.with.overflow.i64(i64 [[T1]], i64 [[T2]]) 29 // CHECK-NEXT: [[T4:%.*]] = extractvalue { i64, i1 } [[T3]], 0 30 // CHECK-NEXT: [[T5:%.*]] = extractvalue { i64, i1 } [[T3]], 1 31 // CHECK: call void @__ubsan_handle_sub_overflow 32 li = lj - lk; 33 } 34 35 // CHECK-LABEL: define void @testlongmul() 36 void testlongmul() { 37 38 // CHECK: [[T1:%.*]] = load i64* @lj 39 // CHECK-NEXT: [[T2:%.*]] = load i64* @lk 40 // CHECK-NEXT: [[T3:%.*]] = call { i64, i1 } @llvm.umul.with.overflow.i64(i64 [[T1]], i64 [[T2]]) 41 // CHECK-NEXT: [[T4:%.*]] = extractvalue { i64, i1 } [[T3]], 0 42 // CHECK-NEXT: [[T5:%.*]] = extractvalue { i64, i1 } [[T3]], 1 43 // CHECK: call void @__ubsan_handle_mul_overflow 44 li = lj * lk; 45 } 46 47 // CHECK-LABEL: define void @testlongpostinc() 48 void testlongpostinc() { 49 opaquelong(li++); 50 51 // CHECK: [[T1:%.*]] = load i64* @li 52 // CHECK-NEXT: [[T2:%.*]] = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 [[T1]], i64 1) 53 // CHECK-NEXT: [[T3:%.*]] = extractvalue { i64, i1 } [[T2]], 0 54 // CHECK-NEXT: [[T4:%.*]] = extractvalue { i64, i1 } [[T2]], 1 55 // CHECK: call void @__ubsan_handle_add_overflow 56 } 57 58 // CHECK-LABEL: define void @testlongpreinc() 59 void testlongpreinc() { 60 opaquelong(++li); 61 62 // CHECK: [[T1:%.*]] = load i64* @li 63 // CHECK-NEXT: [[T2:%.*]] = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 [[T1]], i64 1) 64 // CHECK-NEXT: [[T3:%.*]] = extractvalue { i64, i1 } [[T2]], 0 65 // CHECK-NEXT: [[T4:%.*]] = extractvalue { i64, i1 } [[T2]], 1 66 // CHECK: call void @__ubsan_handle_add_overflow 67 } 68 69 // CHECK-LABEL: define void @testintadd() 70 void testintadd() { 71 72 // CHECK: [[T1:%.*]] = load i32* @ij 73 // CHECK-NEXT: [[T2:%.*]] = load i32* @ik 74 // CHECK-NEXT: [[T3:%.*]] = call { i32, i1 } @llvm.uadd.with.overflow.i32(i32 [[T1]], i32 [[T2]]) 75 // CHECK-NEXT: [[T4:%.*]] = extractvalue { i32, i1 } [[T3]], 0 76 // CHECK-NEXT: [[T5:%.*]] = extractvalue { i32, i1 } [[T3]], 1 77 // CHECK: call void @__ubsan_handle_add_overflow 78 ii = ij + ik; 79 } 80 81 // CHECK-LABEL: define void @testintsub() 82 void testintsub() { 83 84 // CHECK: [[T1:%.*]] = load i32* @ij 85 // CHECK-NEXT: [[T2:%.*]] = load i32* @ik 86 // CHECK-NEXT: [[T3:%.*]] = call { i32, i1 } @llvm.usub.with.overflow.i32(i32 [[T1]], i32 [[T2]]) 87 // CHECK-NEXT: [[T4:%.*]] = extractvalue { i32, i1 } [[T3]], 0 88 // CHECK-NEXT: [[T5:%.*]] = extractvalue { i32, i1 } [[T3]], 1 89 // CHECK: call void @__ubsan_handle_sub_overflow 90 ii = ij - ik; 91 } 92 93 // CHECK-LABEL: define void @testintmul() 94 void testintmul() { 95 96 // CHECK: [[T1:%.*]] = load i32* @ij 97 // CHECK-NEXT: [[T2:%.*]] = load i32* @ik 98 // CHECK-NEXT: [[T3:%.*]] = call { i32, i1 } @llvm.umul.with.overflow.i32(i32 [[T1]], i32 [[T2]]) 99 // CHECK-NEXT: [[T4:%.*]] = extractvalue { i32, i1 } [[T3]], 0 100 // CHECK-NEXT: [[T5:%.*]] = extractvalue { i32, i1 } [[T3]], 1 101 // CHECK: call void @__ubsan_handle_mul_overflow 102 ii = ij * ik; 103 } 104 105 // CHECK-LABEL: define void @testintpostinc() 106 void testintpostinc() { 107 opaqueint(ii++); 108 109 // CHECK: [[T1:%.*]] = load i32* @ii 110 // CHECK-NEXT: [[T2:%.*]] = call { i32, i1 } @llvm.uadd.with.overflow.i32(i32 [[T1]], i32 1) 111 // CHECK-NEXT: [[T3:%.*]] = extractvalue { i32, i1 } [[T2]], 0 112 // CHECK-NEXT: [[T4:%.*]] = extractvalue { i32, i1 } [[T2]], 1 113 // CHECK: call void @__ubsan_handle_add_overflow 114 } 115 116 // CHECK-LABEL: define void @testintpreinc() 117 void testintpreinc() { 118 opaqueint(++ii); 119 120 // CHECK: [[T1:%.*]] = load i32* @ii 121 // CHECK-NEXT: [[T2:%.*]] = call { i32, i1 } @llvm.uadd.with.overflow.i32(i32 [[T1]], i32 1) 122 // CHECK-NEXT: [[T3:%.*]] = extractvalue { i32, i1 } [[T2]], 0 123 // CHECK-NEXT: [[T4:%.*]] = extractvalue { i32, i1 } [[T2]], 1 124 // CHECK: call void @__ubsan_handle_add_overflow 125 } 126