1 // RUN: %clang_cc1 -triple x86_64-gnu-linux -fsanitize=array-bounds,enum,float-cast-overflow,integer-divide-by-zero,implicit-unsigned-integer-truncation,implicit-signed-integer-truncation,implicit-integer-sign-change,unsigned-integer-overflow,signed-integer-overflow,shift-base,shift-exponent -O3 -disable-llvm-passes -emit-llvm -o - %s | FileCheck %s 2 3 4 // CHECK: define void @_Z6BoundsRA10_KiU7_ExtIntILi15EEi 5 void Bounds(const int (&Array)[10], _ExtInt(15) Index) { 6 int I1 = Array[Index]; 7 // CHECK: %[[SEXT:.+]] = sext i15 %{{.+}} to i64 8 // CHECK: %[[CMP:.+]] = icmp ult i64 %[[SEXT]], 10 9 // CHECK: br i1 %[[CMP]] 10 // CHECK: call void @__ubsan_handle_out_of_bounds 11 } 12 13 // CHECK: define void @_Z4Enumv 14 void Enum() { 15 enum E1 { e1a = 0, e1b = 127 } 16 e1; 17 enum E2 { e2a = -1, e2b = 64 } 18 e2; 19 enum E3 { e3a = (1u << 31) - 1 } 20 e3; 21 22 _ExtInt(34) a = e1; 23 // CHECK: %[[E1:.+]] = icmp ule i32 %{{.*}}, 127 24 // CHECK: br i1 %[[E1]] 25 // CHECK: call void @__ubsan_handle_load_invalid_value_abort 26 _ExtInt(34) b = e2; 27 // CHECK: %[[E2HI:.*]] = icmp sle i32 {{.*}}, 127 28 // CHECK: %[[E2LO:.*]] = icmp sge i32 {{.*}}, -128 29 // CHECK: %[[E2:.*]] = and i1 %[[E2HI]], %[[E2LO]] 30 // CHECK: br i1 %[[E2]] 31 // CHECK: call void @__ubsan_handle_load_invalid_value_abort 32 _ExtInt(34) c = e3; 33 // CHECK: %[[E3:.*]] = icmp ule i32 {{.*}}, 2147483647 34 // CHECK: br i1 %[[E3]] 35 // CHECK: call void @__ubsan_handle_load_invalid_value_abort 36 } 37 38 // CHECK: define void @_Z13FloatOverflowfd 39 void FloatOverflow(float f, double d) { 40 _ExtInt(10) E = f; 41 // CHECK: fcmp ogt float %{{.+}}, -5.130000e+02 42 // CHECK: fcmp olt float %{{.+}}, 5.120000e+02 43 _ExtInt(10) E2 = d; 44 // CHECK: fcmp ogt double %{{.+}}, -5.130000e+02 45 // CHECK: fcmp olt double %{{.+}}, 5.120000e+02 46 _ExtInt(7) E3 = f; 47 // CHECK: fcmp ogt float %{{.+}}, -6.500000e+01 48 // CHECK: fcmp olt float %{{.+}}, 6.400000e+01 49 _ExtInt(7) E4 = d; 50 // CHECK: fcmp ogt double %{{.+}}, -6.500000e+01 51 // CHECK: fcmp olt double %{{.+}}, 6.400000e+01 52 } 53 54 // CHECK: define void @_Z14UIntTruncationU7_ExtIntILi35EEjjy 55 void UIntTruncation(unsigned _ExtInt(35) E, unsigned int i, unsigned long long ll) { 56 57 i = E; 58 // CHECK: %[[LOADE:.+]] = load i35 59 // CHECK: %[[CONV:.+]] = trunc i35 %[[LOADE]] to i32 60 // CHECK: %[[EXT:.+]] = zext i32 %[[CONV]] to i35 61 // CHECK: %[[CHECK:.+]] = icmp eq i35 %[[EXT]], %[[LOADE]] 62 // CHECK: br i1 %[[CHECK]] 63 // CHECK: call void @__ubsan_handle_implicit_conversion_abort 64 65 E = ll; 66 // CHECK: %[[LOADLL:.+]] = load i64 67 // CHECK: %[[CONV:.+]] = trunc i64 %[[LOADLL]] to i35 68 // CHECK: %[[EXT:.+]] = zext i35 %[[CONV]] to i64 69 // CHECK: %[[CHECK:.+]] = icmp eq i64 %[[EXT]], %[[LOADLL]] 70 // CHECK: br i1 %[[CHECK]] 71 // CHECK: call void @__ubsan_handle_implicit_conversion_abort 72 } 73 74 // CHECK: define void @_Z13IntTruncationU7_ExtIntILi35EEiU7_ExtIntILi42EEjij 75 void IntTruncation(_ExtInt(35) E, unsigned _ExtInt(42) UE, int i, unsigned j) { 76 77 j = E; 78 // CHECK: %[[LOADE:.+]] = load i35 79 // CHECK: %[[CONV:.+]] = trunc i35 %[[LOADE]] to i32 80 // CHECK: %[[EXT:.+]] = zext i32 %[[CONV]] to i35 81 // CHECK: %[[CHECK:.+]] = icmp eq i35 %[[EXT]], %[[LOADE]] 82 // CHECK: br i1 %[[CHECK]] 83 // CHECK: call void @__ubsan_handle_implicit_conversion_abort 84 85 j = UE; 86 // CHECK: %[[LOADUE:.+]] = load i42 87 // CHECK: %[[CONV:.+]] = trunc i42 %[[LOADUE]] to i32 88 // CHECK: %[[EXT:.+]] = zext i32 %[[CONV]] to i42 89 // CHECK: %[[CHECK:.+]] = icmp eq i42 %[[EXT]], %[[LOADUE]] 90 // CHECK: br i1 %[[CHECK]] 91 // CHECK: call void @__ubsan_handle_implicit_conversion_abort 92 93 // Note: also triggers sign change check. 94 i = UE; 95 // CHECK: %[[LOADUE:.+]] = load i42 96 // CHECK: %[[CONV:.+]] = trunc i42 %[[LOADUE]] to i32 97 // CHECK: %[[NEG:.+]] = icmp slt i32 %[[CONV]], 0 98 // CHECK: %[[SIGNCHECK:.+]] = icmp eq i1 false, %[[NEG]] 99 // CHECK: %[[EXT:.+]] = sext i32 %[[CONV]] to i42 100 // CHECK: %[[CHECK:.+]] = icmp eq i42 %[[EXT]], %[[LOADUE]] 101 // CHECK: %[[CHECKBOTH:.+]] = and i1 %[[SIGNCHECK]], %[[CHECK]] 102 // CHECK: br i1 %[[CHECKBOTH]] 103 // CHECK: call void @__ubsan_handle_implicit_conversion_abort 104 105 // Note: also triggers sign change check. 106 E = UE; 107 // CHECK: %[[LOADUE:.+]] = load i42 108 // CHECK: %[[CONV:.+]] = trunc i42 %[[LOADUE]] to i35 109 // CHECK: %[[NEG:.+]] = icmp slt i35 %[[CONV]], 0 110 // CHECK: %[[SIGNCHECK:.+]] = icmp eq i1 false, %[[NEG]] 111 // CHECK: %[[EXT:.+]] = sext i35 %[[CONV]] to i42 112 // CHECK: %[[CHECK:.+]] = icmp eq i42 %[[EXT]], %[[LOADUE]] 113 // CHECK: %[[CHECKBOTH:.+]] = and i1 %[[SIGNCHECK]], %[[CHECK]] 114 // CHECK: br i1 %[[CHECKBOTH]] 115 // CHECK: call void @__ubsan_handle_implicit_conversion_abort 116 } 117 118 // CHECK: define void @_Z15SignChangeCheckU7_ExtIntILi39EEjU7_ExtIntILi39EEi 119 void SignChangeCheck(unsigned _ExtInt(39) UE, _ExtInt(39) E) { 120 UE = E; 121 // CHECK: %[[LOADE:.+]] = load i39 122 // CHECK: %[[NEG:.+]] = icmp slt i39 %[[LOADE]], 0 123 // CHECK: %[[SIGNCHECK:.+]] = icmp eq i1 %[[NEG]], false 124 // CHECK: br i1 %[[SIGNCHECK]] 125 // CHECK: call void @__ubsan_handle_implicit_conversion_abort 126 127 128 E = UE; 129 // CHECK: %[[LOADUE:.+]] = load i39 130 // CHECK: %[[NEG:.+]] = icmp slt i39 %[[LOADUE]], 0 131 // CHECK: %[[SIGNCHECK:.+]] = icmp eq i1 false, %[[NEG]] 132 // CHECK: br i1 %[[SIGNCHECK]] 133 // CHECK: call void @__ubsan_handle_implicit_conversion_abort 134 } 135 136 // CHECK: define void @_Z9DivByZeroU7_ExtIntILi11EEii 137 void DivByZero(_ExtInt(11) E, int i) { 138 139 // Also triggers signed integer overflow. 140 E / E; 141 // CHECK: %[[E:.+]] = load i11, i11* 142 // CHECK: %[[E2:.+]] = load i11, i11* 143 // CHECK: %[[NEZERO:.+]] = icmp ne i11 %[[E2]], 0 144 // CHECK: %[[NEMIN:.+]] = icmp ne i11 %[[E]], -1024 145 // CHECK: %[[NENEG1:.+]] = icmp ne i11 %[[E2]], -1 146 // CHECK: %[[OR:.+]] = or i1 %[[NEMIN]], %[[NENEG1]] 147 // CHECK: %[[AND:.+]] = and i1 %[[NEZERO]], %[[OR]] 148 // CHECK: br i1 %[[AND]] 149 // CHECK: call void @__ubsan_handle_divrem_overflow_abort 150 } 151 152 // TODO: 153 //-fsanitize=shift: (shift-base, shift-exponent) Shift operators where the amount shifted is greater or equal to the promoted bit-width of the left hand side or less than zero, or where the left hand side is negative. For a signed left shift, also checks for signed overflow in C, and for unsigned overflow in C++. You can use -fsanitize=shift-base or -fsanitize=shift-exponent to check only left-hand side or right-hand side of shift operation, respectively. 154 // CHECK: define void @_Z6ShiftsU7_ExtIntILi9EEi 155 void Shifts(_ExtInt(9) E) { 156 E >> E; 157 // CHECK: %[[LHSE:.+]] = load i9, i9* 158 // CHECK: %[[RHSE:.+]] = load i9, i9* 159 // CHECK: %[[CMP:.+]] = icmp ule i9 %[[RHSE]], 8 160 // CHECK: br i1 %[[CMP]] 161 // CHECK: call void @__ubsan_handle_shift_out_of_bounds_abort 162 163 E << E; 164 // CHECK: %[[LHSE:.+]] = load i9, i9* 165 // CHECK: %[[RHSE:.+]] = load i9, i9* 166 // CHECK: %[[CMP:.+]] = icmp ule i9 %[[RHSE]], 8 167 // CHECK: br i1 %[[CMP]] 168 // CHECK: %[[ZEROS:.+]] = sub nuw nsw i9 8, %[[RHSE]] 169 // CHECK: %[[CHECK:.+]] = lshr i9 %[[LHSE]], %[[ZEROS]] 170 // CHECK: %[[SKIPSIGN:.+]] = lshr i9 %[[CHECK]], 1 171 // CHECK: %[[CHECK:.+]] = icmp eq i9 %[[SKIPSIGN]] 172 // CHECK: %[[PHI:.+]] = phi i1 [ true, %{{.+}} ], [ %[[CHECK]], %{{.+}} ] 173 // CHECK: and i1 %[[CMP]], %[[PHI]] 174 // CHECK: call void @__ubsan_handle_shift_out_of_bounds_abort 175 } 176 177 // CHECK: define void @_Z21SignedIntegerOverflowU7_ExtIntILi93EEiU7_ExtIntILi4EEiU7_ExtIntILi31EEi 178 void SignedIntegerOverflow(_ExtInt(93) BiggestE, 179 _ExtInt(4) SmallestE, 180 _ExtInt(31) JustRightE) { 181 BiggestE + BiggestE; 182 // CHECK: %[[LOAD1:.+]] = load i93, i93* 183 // CHECK: %[[LOAD2:.+]] = load i93, i93* 184 // CHECK: %[[OFCALL:.+]] = call { i93, i1 } @llvm.sadd.with.overflow.i93(i93 %[[LOAD1]], i93 %[[LOAD2]]) 185 // CHECK: %[[EXRESULT:.+]] = extractvalue { i93, i1 } %[[OFCALL]], 0 186 // CHECK: %[[OFRESULT:.+]] = extractvalue { i93, i1 } %[[OFCALL]], 1 187 // CHECK: %[[CHECK:.+]] = xor i1 %[[OFRESULT]], true 188 // CHECK: br i1 %[[CHECK]] 189 // CHECK: call void @__ubsan_handle_add_overflow_abort 190 191 SmallestE - SmallestE; 192 // CHECK: %[[LOAD1:.+]] = load i4, i4* 193 // CHECK: %[[LOAD2:.+]] = load i4, i4* 194 // CHECK: %[[OFCALL:.+]] = call { i4, i1 } @llvm.ssub.with.overflow.i4(i4 %[[LOAD1]], i4 %[[LOAD2]]) 195 // CHECK: %[[EXRESULT:.+]] = extractvalue { i4, i1 } %[[OFCALL]], 0 196 // CHECK: %[[OFRESULT:.+]] = extractvalue { i4, i1 } %[[OFCALL]], 1 197 // CHECK: %[[CHECK:.+]] = xor i1 %[[OFRESULT]], true 198 // CHECK: br i1 %[[CHECK]] 199 // CHECK: call void @__ubsan_handle_sub_overflow_abort 200 201 JustRightE * JustRightE; 202 // CHECK: %[[LOAD1:.+]] = load i31, i31* 203 // CHECK: %[[LOAD2:.+]] = load i31, i31* 204 // CHECK: %[[OFCALL:.+]] = call { i31, i1 } @llvm.smul.with.overflow.i31(i31 %[[LOAD1]], i31 %[[LOAD2]]) 205 // CHECK: %[[EXRESULT:.+]] = extractvalue { i31, i1 } %[[OFCALL]], 0 206 // CHECK: %[[OFRESULT:.+]] = extractvalue { i31, i1 } %[[OFCALL]], 1 207 // CHECK: %[[CHECK:.+]] = xor i1 %[[OFRESULT]], true 208 // CHECK: br i1 %[[CHECK]] 209 // CHECK: call void @__ubsan_handle_mul_overflow_abort 210 } 211 212 // CHECK: define void @_Z23UnsignedIntegerOverflowjU7_ExtIntILi23EEjU7_ExtIntILi35EEj 213 void UnsignedIntegerOverflow(unsigned u, 214 unsigned _ExtInt(23) SmallE, 215 unsigned _ExtInt(35) BigE) { 216 u = SmallE + SmallE; 217 // CHECK: %[[LOADE1:.+]] = load i23, i23* 218 // CHECK: %[[LOADE2:.+]] = load i23, i23* 219 // CHECK: %[[OFCALL:.+]] = call { i23, i1 } @llvm.uadd.with.overflow.i23(i23 %[[LOADE1]], i23 %[[LOADE2]]) 220 // CHECK: %[[EXRESULT:.+]] = extractvalue { i23, i1 } %[[OFCALL]], 0 221 // CHECK: %[[OFRESULT:.+]] = extractvalue { i23, i1 } %[[OFCALL]], 1 222 // CHECK: %[[CHECK:.+]] = xor i1 %[[OFRESULT]], true 223 // CHECK: br i1 %[[CHECK]] 224 // CHECK: call void @__ubsan_handle_add_overflow_abort 225 226 SmallE = u + u; 227 // CHECK: %[[LOADU1:.+]] = load i32, i32* 228 // CHECK: %[[LOADU2:.+]] = load i32, i32* 229 // CHECK: %[[OFCALL:.+]] = call { i32, i1 } @llvm.uadd.with.overflow.i32(i32 %[[LOADU1]], i32 %[[LOADU2]]) 230 // CHECK: %[[EXRESULT:.+]] = extractvalue { i32, i1 } %[[OFCALL]], 0 231 // CHECK: %[[OFRESULT:.+]] = extractvalue { i32, i1 } %[[OFCALL]], 1 232 // CHECK: %[[CHECK:.+]] = xor i1 %[[OFRESULT]], true 233 // CHECK: br i1 %[[CHECK]] 234 // CHECK: call void @__ubsan_handle_add_overflow_abort 235 236 SmallE = SmallE + SmallE; 237 // CHECK: %[[LOADE1:.+]] = load i23, i23* 238 // CHECK: %[[LOADE2:.+]] = load i23, i23* 239 // CHECK: %[[OFCALL:.+]] = call { i23, i1 } @llvm.uadd.with.overflow.i23(i23 %[[LOADE1]], i23 %[[LOADE2]]) 240 // CHECK: %[[EXRESULT:.+]] = extractvalue { i23, i1 } %[[OFCALL]], 0 241 // CHECK: %[[OFRESULT:.+]] = extractvalue { i23, i1 } %[[OFCALL]], 1 242 // CHECK: %[[CHECK:.+]] = xor i1 %[[OFRESULT]], true 243 // CHECK: br i1 %[[CHECK]] 244 // CHECK: call void @__ubsan_handle_add_overflow_abort 245 246 SmallE = BigE + BigE; 247 // CHECK: %[[LOADE1:.+]] = load i35, i35* 248 // CHECK: %[[LOADE2:.+]] = load i35, i35* 249 // CHECK: %[[OFCALL:.+]] = call { i35, i1 } @llvm.uadd.with.overflow.i35(i35 %[[LOADE1]], i35 %[[LOADE2]]) 250 // CHECK: %[[EXRESULT:.+]] = extractvalue { i35, i1 } %[[OFCALL]], 0 251 // CHECK: %[[OFRESULT:.+]] = extractvalue { i35, i1 } %[[OFCALL]], 1 252 // CHECK: %[[CHECK:.+]] = xor i1 %[[OFRESULT]], true 253 // CHECK: br i1 %[[CHECK]] 254 // CHECK: call void @__ubsan_handle_add_overflow_abort 255 256 BigE = BigE + BigE; 257 // CHECK: %[[LOADE1:.+]] = load i35, i35* 258 // CHECK: %[[LOADE2:.+]] = load i35, i35* 259 // CHECK: %[[OFCALL:.+]] = call { i35, i1 } @llvm.uadd.with.overflow.i35(i35 %[[LOADE1]], i35 %[[LOADE2]]) 260 // CHECK: %[[EXRESULT:.+]] = extractvalue { i35, i1 } %[[OFCALL]], 0 261 // CHECK: %[[OFRESULT:.+]] = extractvalue { i35, i1 } %[[OFCALL]], 1 262 // CHECK: %[[CHECK:.+]] = xor i1 %[[OFRESULT]], true 263 // CHECK: br i1 %[[CHECK]] 264 // CHECK: call void @__ubsan_handle_add_overflow_abort 265 } 266