brintos

brintos / llvm-project-archived public Read only

0
0
Text · 14.2 KiB · f7c6db7 Raw
312 lines · cpp
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 %s2 3 4// CHECK: define{{.*}} void @_Z6BoundsRA10_KiDB15_5void Bounds(const int (&Array)[10], _BitInt(15) Index) {6  int I1 = Array[Index];7  // CHECK: %[[SEXT:.+]] = sext i15 %{{.+}} to i648  // CHECK: %[[CMP:.+]] = icmp ult i64 %[[SEXT]], 109  // CHECK: br i1 %[[CMP]]10  // CHECK: call void @__ubsan_handle_out_of_bounds11}12 13// CHECK: define{{.*}} void @_Z4Enumv14void 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  _BitInt(34) a = e1;23  // CHECK: %[[E1:.+]] = icmp ule i32 %{{.*}}, 12724  // CHECK: br i1 %[[E1]]25  // CHECK: call void @__ubsan_handle_load_invalid_value_abort26  _BitInt(34) b = e2;27  // CHECK: %[[E2HI:.*]] = icmp sle i32 {{.*}}, 12728  // CHECK: %[[E2LO:.*]] = icmp sge i32 {{.*}}, -12829  // CHECK: %[[E2:.*]] = and i1 %[[E2HI]], %[[E2LO]]30  // CHECK: br i1 %[[E2]]31  // CHECK: call void @__ubsan_handle_load_invalid_value_abort32  _BitInt(34) c = e3;33  // CHECK: %[[E3:.*]] = icmp ule i32 {{.*}}, 214748364734  // CHECK: br i1 %[[E3]]35  // CHECK: call void @__ubsan_handle_load_invalid_value_abort36}37 38// CHECK: define{{.*}} void @_Z13FloatOverflowfd39void FloatOverflow(float f, double d) {40  _BitInt(10) E = f;41  // CHECK: fcmp ogt float %{{.+}}, -5.130000e+0242  // CHECK: fcmp olt float %{{.+}}, 5.120000e+0243  _BitInt(10) E2 = d;44  // CHECK: fcmp ogt double %{{.+}}, -5.130000e+0245  // CHECK: fcmp olt double %{{.+}}, 5.120000e+0246  _BitInt(7) E3 = f;47  // CHECK: fcmp ogt float %{{.+}}, -6.500000e+0148  // CHECK: fcmp olt float %{{.+}}, 6.400000e+0149  _BitInt(7) E4 = d;50  // CHECK: fcmp ogt double %{{.+}}, -6.500000e+0151  // CHECK: fcmp olt double %{{.+}}, 6.400000e+0152}53 54// CHECK: define{{.*}} void @_Z14UIntTruncationDU35_jy55void UIntTruncation(unsigned _BitInt(35) E, unsigned int i, unsigned long long ll) {56 57  i = E;58  // CHECK: %[[LOADE:.+]] = load i6459  // CHECK: %[[E1:.+]] = trunc i64 %[[LOADE]] to i3560  // CHECK: %[[STOREDV:.+]] = zext i35 %[[E1]] to i6461  // CHECK: store i64 %[[STOREDV]], ptr %[[EADDR:.+]]62  // CHECK: %[[LOADE2:.+]] = load i64, ptr %[[EADDR]]63  // CHECK: %[[LOADEDV:.+]] = trunc i64 %[[LOADE2]] to i3564  // CHECK: %[[CONV:.+]] = trunc i35 %[[LOADEDV]] to i3265  // CHECK: %[[EXT:.+]] = zext i32 %[[CONV]] to i3566  // CHECK: %[[CHECK:.+]] = icmp eq i35 %[[EXT]], %[[LOADEDV]]67  // CHECK: br i1 %[[CHECK]]68  // CHECK: call void @__ubsan_handle_implicit_conversion_abort69 70  E = ll;71  // CHECK: %[[LOADLL:.+]] = load i6472  // CHECK: %[[CONV:.+]] = trunc i64 %[[LOADLL]] to i3573  // CHECK: %[[EXT:.+]] = zext i35 %[[CONV]] to i6474  // CHECK: %[[CHECK:.+]] = icmp eq i64 %[[EXT]], %[[LOADLL]]75  // CHECK: br i1 %[[CHECK]]76  // CHECK: call void @__ubsan_handle_implicit_conversion_abort77}78 79// CHECK: define{{.*}} void @_Z13IntTruncationDB35_DU42_ij80void IntTruncation(_BitInt(35) E, unsigned _BitInt(42) UE, int i, unsigned j) {81 82  j = E;83  // CHECK: %[[LOADE:.+]] = load i6484  // CHECK: %[[E1:.+]] = trunc i64 %[[LOADE]] to i3585  // CHECK: %[[STOREDV:.+]] = sext i35 %[[E1]] to i6486  // CHECK: store i64 %[[STOREDV]], ptr %[[EADDR:.+]]87  // CHECK: %[[LOADE2:.+]] = load i64, ptr %[[EADDR]]88  // CHECK: %[[LOADEDV:.+]] = trunc i64 %[[LOADE2]] to i3589  // CHECK: %[[CONV:.+]] = trunc i35 %[[LOADEDV]] to i3290  // CHECK: %[[EXT:.+]] = zext i32 %[[CONV]] to i3591  // CHECK: %[[CHECK:.+]] = icmp eq i35 %[[EXT]], %[[LOADEDV]]92  // CHECK: br i1 %[[CHECK]]93  // CHECK: call void @__ubsan_handle_implicit_conversion_abort94 95  j = UE;96  // CHECK: %[[LOADUE:.+]] = load i6497  // CHECK: %[[LOADEDV:.+]] = trunc i64 %[[LOADUE]] to i4298  // CHECK: %[[CONV:.+]] = trunc i42 %[[LOADEDV]] to i3299  // CHECK: %[[EXT:.+]] = zext i32 %[[CONV]] to i42100  // CHECK: %[[CHECK:.+]] = icmp eq i42 %[[EXT]], %[[LOADEDV]]101  // CHECK: br i1 %[[CHECK]]102  // CHECK: call void @__ubsan_handle_implicit_conversion_abort103 104  // Note: also triggers sign change check.105  i = UE;106  // CHECK: %[[LOADUE:.+]] = load i64107  // CHECK: %[[LOADEDV:.+]] = trunc i64 %[[LOADUE]] to i42108  // CHECK: %[[CONV:.+]] = trunc i42 %[[LOADEDV]] to i32109  // CHECK: %[[NEG:.+]] = icmp slt i32 %[[CONV]], 0110  // CHECK: %[[SIGNCHECK:.+]] = icmp eq i1 false, %[[NEG]]111  // CHECK: %[[EXT:.+]] = sext i32 %[[CONV]] to i42112  // CHECK: %[[CHECK:.+]] = icmp eq i42 %[[EXT]], %[[LOADEDV]]113  // CHECK: %[[CHECKBOTH:.+]] = and i1 %[[SIGNCHECK]], %[[CHECK]]114  // CHECK: br i1 %[[CHECKBOTH]]115  // CHECK: call void @__ubsan_handle_implicit_conversion_abort116 117  // Note: also triggers sign change check.118  E = UE;119  // CHECK: %[[LOADUE:.+]] = load i64120  // CHECK: %[[LOADEDV:.+]] = trunc i64 %[[LOADUE]] to i42121  // CHECK: %[[CONV:.+]] = trunc i42 %[[LOADEDV]] to i35122  // CHECK: %[[NEG:.+]] = icmp slt i35 %[[CONV]], 0123  // CHECK: %[[SIGNCHECK:.+]] = icmp eq i1 false, %[[NEG]]124  // CHECK: %[[EXT:.+]] = sext i35 %[[CONV]] to i42125  // CHECK: %[[CHECK:.+]] = icmp eq i42 %[[EXT]], %[[LOADEDV]]126  // CHECK: %[[CHECKBOTH:.+]] = and i1 %[[SIGNCHECK]], %[[CHECK]]127  // CHECK: br i1 %[[CHECKBOTH]]128  // CHECK: call void @__ubsan_handle_implicit_conversion_abort129}130 131// CHECK: define{{.*}} void @_Z15SignChangeCheckDU39_DB39_132void SignChangeCheck(unsigned _BitInt(39) UE, _BitInt(39) E) {133  UE = E;134  // CHECK: %[[LOADEU:.+]] = load i64135  // CHECK: %[[LOADE:.+]] = load i64136  // CHECK: %[[LOADEDV:.+]] = trunc i64 %[[LOADE]] to i39137  // CHECK: %[[STOREDV:.+]] = sext i39 %[[LOADEDV]] to i64138  // CHECK: store i64 %[[STOREDV]], ptr %[[EADDR:.+]]139  // CHECK: %[[LOADE2:.+]] = load i64, ptr %[[EADDR]]140  // CHECK: %[[LOADEDV2:.+]] = trunc i64 %[[LOADE2]] to i39141  // CHECK: %[[NEG:.+]] = icmp slt i39 %[[LOADEDV2]], 0142  // CHECK: %[[SIGNCHECK:.+]] = icmp eq i1 %[[NEG]], false143  // CHECK: br i1 %[[SIGNCHECK]]144  // CHECK: call void @__ubsan_handle_implicit_conversion_abort145 146  E = UE;147  // CHECK: %[[STOREDV2:.+]] = zext i39 %[[LOADEDV2]] to i64148  // CHECK: store i64 %[[STOREDV2]], ptr %[[UEADDR:.+]]149  // CHECK: %[[LOADUE2:.+]] = load i64, ptr %[[UEADDR]]150  // CHECK: %[[LOADEDV3:.+]] = trunc i64 %[[LOADUE2]] to i39151  // CHECK: %[[NEG:.+]] = icmp slt i39 %[[LOADEDV3]], 0152  // CHECK: %[[SIGNCHECK:.+]] = icmp eq i1 false, %[[NEG]]153  // CHECK: br i1 %[[SIGNCHECK]]154  // CHECK: call void @__ubsan_handle_implicit_conversion_abort155}156 157// CHECK: define{{.*}} void @_Z9DivByZeroDB11_i158void DivByZero(_BitInt(11) E, int i) {159 160  // Also triggers signed integer overflow.161  E / E;162  // CHECK: %[[EADDR:.+]] = alloca i16163  // CHECK: %[[E:.+]] = load i16, ptr %[[EADDR]]164  // CHECK: %[[LOADEDE:.+]] = trunc i16 %[[E]] to i11165  // CHECK: %[[E2:.+]] = load i16, ptr %[[EADDR]]166  // CHECK: %[[LOADEDE2:.+]] = trunc i16 %[[E2]] to i11167  // CHECK: %[[NEZERO:.+]] = icmp ne i11 %[[LOADEDE2]], 0168  // CHECK: %[[NEMIN:.+]] = icmp ne i11 %[[LOADEDE]], -1024169  // CHECK: %[[NENEG1:.+]] = icmp ne i11 %[[LOADEDE2]], -1170  // CHECK: %[[OR:.+]] = or i1 %[[NEMIN]], %[[NENEG1]]171  // CHECK: %[[AND:.+]] = and i1 %[[NEZERO]], %[[OR]]172  // CHECK: br i1 %[[AND]]173  // CHECK: call void @__ubsan_handle_divrem_overflow_abort174}175 176// TODO:177//-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.178// CHECK: define{{.*}} void @_Z6ShiftsDB9_179void Shifts(_BitInt(9) E) {180  E >> E;181  // CHECK: %[[EADDR:.+]] = alloca i16182  // CHECK: %[[LHSE:.+]] = load i16, ptr %[[EADDR]]183  // CHECK: %[[RHSE:.+]] = load i16, ptr %[[EADDR]]184  // CHECK: %[[LOADED:.+]] = trunc i16 %[[RHSE]] to i9185  // CHECK: %[[CMP:.+]] = icmp ule i9 %[[LOADED]], 8186  // CHECK: br i1 %[[CMP]]187  // CHECK: call void @__ubsan_handle_shift_out_of_bounds_abort188 189  E << E;190  // CHECK: %[[LHSE:.+]] = load i16, ptr191  // CHECK: %[[LOADEDL:.+]] = trunc i16 %[[LHSE]] to i9192  // CHECK: %[[RHSE:.+]] = load i16, ptr193  // CHECK: %[[LOADED:.+]] = trunc i16 %[[RHSE]] to i9194  // CHECK: %[[CMP:.+]] = icmp ule i9 %[[LOADED]], 8195  // CHECK: br i1 %[[CMP]]196  // CHECK: %[[ZEROS:.+]] = sub nuw nsw i9 8, %[[LOADED]]197  // CHECK: %[[CHECK:.+]] = lshr i9 %[[LOADEDL]], %[[ZEROS]]198  // CHECK: %[[SKIPSIGN:.+]] = lshr i9 %[[CHECK]], 1199  // CHECK: %[[CHECK:.+]] = icmp eq i9 %[[SKIPSIGN]]200  // CHECK: %[[PHI:.+]] = phi i1 [ true, %{{.+}} ], [ %[[CHECK]], %{{.+}} ]201  // CHECK: and i1 %[[CMP]], %[[PHI]]202  // CHECK: call void @__ubsan_handle_shift_out_of_bounds_abort203}204 205// CHECK: define{{.*}} void @_Z21SignedIntegerOverflowDB93_DB4_DB31_206void SignedIntegerOverflow(_BitInt(93) BiggestE,207                           _BitInt(4) SmallestE,208                           _BitInt(31) JustRightE) {209  BiggestE + BiggestE;210  // CHECK: %[[LOADBIGGESTE2:.+]] = load i128211  // CHECK: %[[LOADEDV:.+]] = trunc i128 %[[LOADBIGGESTE2]] to i93212  // CHECK: %[[STOREDV:.+]] = sext i93 %[[LOADEDV]] to i128213  // CHECK: store i128 %[[STOREDV]], ptr %[[BIGGESTEADDR:.+]]214  // CHECK: %[[LOAD1:.+]] = load i128, ptr %[[BIGGESTEADDR]]215  // CHECK: %[[LOADEDV1:.+]] = trunc i128 %[[LOAD1]] to i93216  // CHECK: %[[LOAD2:.+]] = load i128, ptr %[[BIGGESTEADDR]]217  // CHECK: %[[LOADEDV2:.+]] = trunc i128 %[[LOAD2]] to i93218  // CHECK: %[[OFCALL:.+]] = call { i93, i1 } @llvm.sadd.with.overflow.i93(i93 %[[LOADEDV1]], i93 %[[LOADEDV2]])219  // CHECK: %[[EXRESULT:.+]] = extractvalue { i93, i1 } %[[OFCALL]], 0220  // CHECK: %[[OFRESULT:.+]] = extractvalue { i93, i1 } %[[OFCALL]], 1221  // CHECK: %[[CHECK:.+]] = xor i1 %[[OFRESULT]], true222  // CHECK: br i1 %[[CHECK]]223  // CHECK: call void @__ubsan_handle_add_overflow_abort224 225  SmallestE - SmallestE;226  // CHECK: %[[LOAD1:.+]] = load i8, ptr227  // CHECK: %[[LOADEDV1:.+]] = trunc i8 %[[LOAD1]] to i4228  // CHECK: %[[LOAD2:.+]] = load i8, ptr229  // CHECK: %[[LOADEDV2:.+]] = trunc i8 %[[LOAD2]] to i4230  // CHECK: %[[OFCALL:.+]] = call { i4, i1 } @llvm.ssub.with.overflow.i4(i4 %[[LOADEDV1]], i4 %[[LOADEDV2]])231  // CHECK: %[[EXRESULT:.+]] = extractvalue { i4, i1 } %[[OFCALL]], 0232  // CHECK: %[[OFRESULT:.+]] = extractvalue { i4, i1 } %[[OFCALL]], 1233  // CHECK: %[[CHECK:.+]] = xor i1 %[[OFRESULT]], true234  // CHECK: br i1 %[[CHECK]]235  // CHECK: call void @__ubsan_handle_sub_overflow_abort236 237  JustRightE * JustRightE;238  // CHECK: %[[LOAD1:.+]] = load i32, ptr239  // CHECK: %[[LOADEDV1:.+]] = trunc i32 %[[LOAD1]] to i31240  // CHECK: %[[LOAD2:.+]] = load i32, ptr241  // CHECK: %[[LOADEDV2:.+]] = trunc i32 %[[LOAD2]] to i31242  // CHECK: %[[OFCALL:.+]] = call { i31, i1 } @llvm.smul.with.overflow.i31(i31 %[[LOADEDV1]], i31 %[[LOADEDV2]])243  // CHECK: %[[EXRESULT:.+]] = extractvalue { i31, i1 } %[[OFCALL]], 0244  // CHECK: %[[OFRESULT:.+]] = extractvalue { i31, i1 } %[[OFCALL]], 1245  // CHECK: %[[CHECK:.+]] = xor i1 %[[OFRESULT]], true246  // CHECK: br i1 %[[CHECK]]247  // CHECK: call void @__ubsan_handle_mul_overflow_abort248}249 250// CHECK: define{{.*}} void @_Z23UnsignedIntegerOverflowjDU23_DU35_251void UnsignedIntegerOverflow(unsigned u,252                             unsigned _BitInt(23) SmallE,253                             unsigned _BitInt(35) BigE) {254  u = SmallE + SmallE;255  // CHECK: %[[LOADE1:.+]] = load i32, ptr256  // CHECK-NEXT: %[[LOADEDV1:.+]] = trunc i32 %[[LOADE1]] to i23257  // CHECK: %[[LOADE2:.+]] = load i32, ptr258  // CHECK-NEXT: %[[LOADEDV2:.+]] = trunc i32 %[[LOADE2]] to i23259  // CHECK: %[[OFCALL:.+]] = call { i23, i1 } @llvm.uadd.with.overflow.i23(i23 %[[LOADEDV1]], i23 %[[LOADEDV2]])260  // CHECK: %[[EXRESULT:.+]] = extractvalue { i23, i1 } %[[OFCALL]], 0261  // CHECK: %[[OFRESULT:.+]] = extractvalue { i23, i1 } %[[OFCALL]], 1262  // CHECK: %[[CHECK:.+]] = xor i1 %[[OFRESULT]], true263  // CHECK: br i1 %[[CHECK]]264  // CHECK: call void @__ubsan_handle_add_overflow_abort265 266  SmallE = u + u;267  // CHECK: %[[LOADU1:.+]] = load i32, ptr268  // CHECK: %[[LOADU2:.+]] = load i32, ptr269  // CHECK: %[[OFCALL:.+]] = call { i32, i1 } @llvm.uadd.with.overflow.i32(i32 %[[LOADU1]], i32 %[[LOADU2]])270  // CHECK: %[[EXRESULT:.+]] = extractvalue { i32, i1 } %[[OFCALL]], 0271  // CHECK: %[[OFRESULT:.+]] = extractvalue { i32, i1 } %[[OFCALL]], 1272  // CHECK: %[[CHECK:.+]] = xor i1 %[[OFRESULT]], true273  // CHECK: br i1 %[[CHECK]]274  // CHECK: call void @__ubsan_handle_add_overflow_abort275 276  SmallE = SmallE + SmallE;277  // CHECK: %[[LOADE1:.+]] = load i32, ptr278  // CHECK-NEXT: %[[LOADEDV1:.+]] = trunc i32 %[[LOADE1]] to i23279  // CHECK: %[[LOADE2:.+]] = load i32, ptr280  // CHECK-NEXT: %[[LOADEDV2:.+]] = trunc i32 %[[LOADE2]] to i23281  // CHECK: %[[OFCALL:.+]] = call { i23, i1 } @llvm.uadd.with.overflow.i23(i23 %[[LOADEDV1]], i23 %[[LOADEDV2]])282  // CHECK: %[[EXRESULT:.+]] = extractvalue { i23, i1 } %[[OFCALL]], 0283  // CHECK: %[[OFRESULT:.+]] = extractvalue { i23, i1 } %[[OFCALL]], 1284  // CHECK: %[[CHECK:.+]] = xor i1 %[[OFRESULT]], true285  // CHECK: br i1 %[[CHECK]]286  // CHECK: call void @__ubsan_handle_add_overflow_abort287 288  SmallE = BigE + BigE;289  // CHECK: %[[LOADE1:.+]] = load i64, ptr290  // CHECK-NEXT: %[[LOADEDV1:.+]] = trunc i64 %[[LOADE1]] to i35291  // CHECK: %[[LOADE2:.+]] = load i64, ptr292  // CHECK-NEXT: %[[LOADEDV2:.+]] = trunc i64 %[[LOADE2]] to i35293  // CHECK: %[[OFCALL:.+]] = call { i35, i1 } @llvm.uadd.with.overflow.i35(i35 %[[LOADEDV1]], i35 %[[LOADEDV2]])294  // CHECK: %[[EXRESULT:.+]] = extractvalue { i35, i1 } %[[OFCALL]], 0295  // CHECK: %[[OFRESULT:.+]] = extractvalue { i35, i1 } %[[OFCALL]], 1296  // CHECK: %[[CHECK:.+]] = xor i1 %[[OFRESULT]], true297  // CHECK: br i1 %[[CHECK]]298  // CHECK: call void @__ubsan_handle_add_overflow_abort299 300  BigE = BigE + BigE;301  // CHECK: %[[LOADE1:.+]] = load i64, ptr302  // CHECK-NEXT: %[[LOADEDV1:.+]] = trunc i64 %[[LOADE1]] to i35303  // CHECK: %[[LOADE2:.+]] = load i64, ptr304  // CHECK-NEXT: %[[LOADEDV2:.+]] = trunc i64 %[[LOADE2]] to i35305  // CHECK: %[[OFCALL:.+]] = call { i35, i1 } @llvm.uadd.with.overflow.i35(i35 %[[LOADEDV1]], i35 %[[LOADEDV2]])306  // CHECK: %[[EXRESULT:.+]] = extractvalue { i35, i1 } %[[OFCALL]], 0307  // CHECK: %[[OFRESULT:.+]] = extractvalue { i35, i1 } %[[OFCALL]], 1308  // CHECK: %[[CHECK:.+]] = xor i1 %[[OFRESULT]], true309  // CHECK: br i1 %[[CHECK]]310  // CHECK: call void @__ubsan_handle_add_overflow_abort311}312