1 // RUN: %clang_cc1 -no-opaque-pointers -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s --check-prefix=CHECK 2 // RUN: %clang_cc1 -no-opaque-pointers -fsanitize=implicit-integer-sign-change -fno-sanitize-recover=implicit-integer-sign-change -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s -implicit-check-not="call void @__ubsan_handle_implicit_conversion" --check-prefixes=CHECK,CHECK-SANITIZE,CHECK-SANITIZE-ANYRECOVER,CHECK-SANITIZE-NORECOVER,CHECK-SANITIZE-UNREACHABLE 3 // RUN: %clang_cc1 -no-opaque-pointers -fsanitize=implicit-integer-sign-change -fsanitize-recover=implicit-integer-sign-change -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s -implicit-check-not="call void @__ubsan_handle_implicit_conversion" --check-prefixes=CHECK,CHECK-SANITIZE,CHECK-SANITIZE-ANYRECOVER,CHECK-SANITIZE-RECOVER 4 // RUN: %clang_cc1 -no-opaque-pointers -fsanitize=implicit-integer-sign-change -fsanitize-trap=implicit-integer-sign-change -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s -implicit-check-not="call void @__ubsan_handle_implicit_conversion" --check-prefixes=CHECK,CHECK-SANITIZE,CHECK-SANITIZE-TRAP,CHECK-SANITIZE-UNREACHABLE 5 6 // CHECK-SANITIZE-ANYRECOVER: @[[UNSIGNED_INT:.*]] = {{.*}} c"'unsigned int'\00" } 7 // CHECK-SANITIZE-ANYRECOVER-NEXT: @[[SIGNED_INT:.*]] = {{.*}} c"'int'\00" } 8 // CHECK-SANITIZE-ANYRECOVER-NEXT: @[[LINE_100:.*]] = {{.*}}, i32 100, i32 10 }, {{.*}}* @[[UNSIGNED_INT]], {{.*}}* @[[SIGNED_INT]], i8 3 } 9 // CHECK-SANITIZE-ANYRECOVER-NEXT: @[[LINE_200:.*]] = {{.*}}, i32 200, i32 10 }, {{.*}}* @[[SIGNED_INT]], {{.*}}* @[[UNSIGNED_INT]], i8 3 } 10 // CHECK-SANITIZE-ANYRECOVER-NEXT: @[[UNSIGNED_CHAR:.*]] = {{.*}} c"'unsigned char'\00" } 11 // CHECK-SANITIZE-ANYRECOVER-NEXT: @[[LINE_300:.*]] = {{.*}}, i32 300, i32 10 }, {{.*}}* @[[SIGNED_INT]], {{.*}}* @[[UNSIGNED_CHAR]], i8 3 } 12 // CHECK-SANITIZE-ANYRECOVER-NEXT: @[[SIGNED_CHAR:.*]] = {{.*}} c"'signed char'\00" } 13 // CHECK-SANITIZE-ANYRECOVER-NEXT: @[[LINE_400:.*]] = {{.*}}, i32 400, i32 10 }, {{.*}}* @[[SIGNED_CHAR]], {{.*}}* @[[UNSIGNED_CHAR]], i8 3 } 14 // CHECK-SANITIZE-ANYRECOVER-NEXT: @[[LINE_500:.*]] = {{.*}}, i32 500, i32 10 }, {{.*}}* @[[UNSIGNED_CHAR]], {{.*}}* @[[SIGNED_CHAR]], i8 3 } 15 // CHECK-SANITIZE-ANYRECOVER-NEXT: @[[LINE_600:.*]] = {{.*}}, i32 600, i32 10 }, {{.*}}* @[[SIGNED_CHAR]], {{.*}}* @[[UNSIGNED_INT]], i8 3 } 16 // CHECK-SANITIZE-ANYRECOVER-NEXT: @[[LINE_700:.*]] = {{.*}}, i32 700, i32 10 }, {{.*}}* @[[UNSIGNED_INT]], {{.*}}* @[[SIGNED_CHAR]], i8 3 } 17 // CHECK-SANITIZE-ANYRECOVER-NEXT: @[[LINE_800:.*]] = {{.*}}, i32 800, i32 10 }, {{.*}}* @[[SIGNED_INT]], {{.*}}* @[[SIGNED_CHAR]], i8 3 } 18 // CHECK-SANITIZE-ANYRECOVER: @[[UINT32:.*]] = {{.*}} c"'uint32_t' (aka 'unsigned int')\00" } 19 // CHECK-SANITIZE-ANYRECOVER: @[[INT32:.*]] = {{.*}} c"'int32_t' (aka 'int')\00" } 20 // CHECK-SANITIZE-ANYRECOVER: @[[LINE_900:.*]] = {{.*}}, i32 900, i32 10 }, {{.*}}* @[[UINT32]], {{.*}}* @[[INT32]], i8 3 } 21 22 // ========================================================================== // 23 // The expected true-positives. 24 // These are implicit, potentially sign-altering, conversions. 25 // ========================================================================== // 26 27 // These 3 result (after optimizations) in simple 'icmp sge i32 %src, 0'. 28 29 // CHECK-LABEL: @unsigned_int_to_signed_int 30 // CHECK-SAME: i32 noundef %[[SRC:.*]]) 31 signed int unsigned_int_to_signed_int(unsigned int src) { 32 // CHECK: %[[SRC_ADDR:.*]] = alloca i32 33 // CHECK-NEXT: store i32 %[[SRC]], i32* %[[SRC_ADDR]] 34 // CHECK-NEXT: %[[DST:.*]] = load i32, i32* %[[SRC_ADDR]] 35 // CHECK-SANITIZE-NEXT: %[[DST_NEGATIVITYCHECK:.*]] = icmp slt i32 %[[DST]], 0, !nosanitize 36 // CHECK-SANITIZE-NEXT: %[[SIGNCHANGECHECK:.*]] = icmp eq i1 false, %[[DST_NEGATIVITYCHECK]], !nosanitize 37 // CHECK-SANITIZE-NEXT: br i1 %[[SIGNCHANGECHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize 38 // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]: 39 // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[DST]] to i64, !nosanitize 40 // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i32 %[[DST]] to i64, !nosanitize 41 // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_100]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize 42 // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_100]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize 43 // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.ubsantrap(i8 7){{.*}}, !nosanitize 44 // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize 45 // CHECK-SANITIZE: [[CONT]]: 46 // CHECK-NEXT: ret i32 %[[DST]] 47 // CHECK-NEXT: } 48 #line 100 49 return src; 50 } 51 52 // CHECK-LABEL: @signed_int_to_unsigned_int 53 // CHECK-SAME: i32 noundef %[[SRC:.*]]) 54 unsigned int signed_int_to_unsigned_int(signed int src) { 55 // CHECK: %[[SRC_ADDR:.*]] = alloca i32 56 // CHECK-NEXT: store i32 %[[SRC]], i32* %[[SRC_ADDR]] 57 // CHECK-NEXT: %[[DST:.*]] = load i32, i32* %[[SRC_ADDR]] 58 // CHECK-SANITIZE-NEXT: %[[SRC_NEGATIVITYCHECK:.*]] = icmp slt i32 %[[DST]], 0, !nosanitize 59 // CHECK-SANITIZE-NEXT: %[[SIGNCHANGECHECK:.*]] = icmp eq i1 %[[SRC_NEGATIVITYCHECK]], false, !nosanitize 60 // CHECK-SANITIZE-NEXT: br i1 %[[SIGNCHANGECHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize 61 // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]: 62 // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[DST]] to i64, !nosanitize 63 // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i32 %[[DST]] to i64, !nosanitize 64 // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_200]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize 65 // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_200]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize 66 // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.ubsantrap(i8 7){{.*}}, !nosanitize 67 // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize 68 // CHECK-SANITIZE: [[CONT]]: 69 // CHECK-NEXT: ret i32 %[[DST]] 70 // CHECK-NEXT: } 71 #line 200 72 return src; 73 } 74 75 // CHECK-LABEL: @signed_int_to_unsigned_char 76 // CHECK-SAME: i32 noundef %[[SRC:.*]]) 77 unsigned char signed_int_to_unsigned_char(signed int src) { 78 // CHECK: %[[SRC_ADDR:.*]] = alloca i32 79 // CHECK-NEXT: store i32 %[[SRC]], i32* %[[SRC_ADDR]] 80 // CHECK-NEXT: %[[DST:.*]] = load i32, i32* %[[SRC_ADDR]] 81 // CHECK-NEXT: %[[CONV:.*]] = trunc i32 %[[DST]] to i8 82 // CHECK-SANITIZE-NEXT: %[[SRC_NEGATIVITYCHECK:.*]] = icmp slt i32 %[[DST]], 0, !nosanitize 83 // CHECK-SANITIZE-NEXT: %[[SIGNCHANGECHECK:.*]] = icmp eq i1 %[[SRC_NEGATIVITYCHECK]], false, !nosanitize 84 // CHECK-SANITIZE-NEXT: br i1 %[[SIGNCHANGECHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize 85 // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]: 86 // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[DST]] to i64, !nosanitize 87 // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTCONV:.*]] = zext i8 %[[CONV]] to i64, !nosanitize 88 // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_300]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTCONV]]){{.*}}, !nosanitize 89 // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_300]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTCONV]]){{.*}}, !nosanitize 90 // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.ubsantrap(i8 7){{.*}}, !nosanitize 91 // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize 92 // CHECK-SANITIZE: [[CONT]]: 93 // CHECK-NEXT: ret i8 %[[CONV]] 94 // CHECK-NEXT: } 95 #line 300 96 return src; 97 } 98 99 // These 3 result (after optimizations) in simple 'icmp sge i8 %src, 0' 100 101 // CHECK-LABEL: @signed_char_to_unsigned_char 102 // CHECK-SAME: (i8 noundef signext %[[SRC:.*]]) 103 unsigned char signed_char_to_unsigned_char(signed char src) { 104 // CHECK: %[[SRC_ADDR:.*]] = alloca i8 105 // CHECK-NEXT: store i8 %[[SRC]], i8* %[[SRC_ADDR]] 106 // CHECK-NEXT: %[[DST:.*]] = load i8, i8* %[[SRC_ADDR]] 107 // CHECK-SANITIZE-NEXT: %[[SRC_NEGATIVITYCHECK:.*]] = icmp slt i8 %[[DST]], 0, !nosanitize 108 // CHECK-SANITIZE-NEXT: %[[SIGNCHANGECHECK:.*]] = icmp eq i1 %[[SRC_NEGATIVITYCHECK]], false, !nosanitize 109 // CHECK-SANITIZE-NEXT: br i1 %[[SIGNCHANGECHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize 110 // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]: 111 // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i8 %[[DST]] to i64, !nosanitize 112 // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize 113 // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_400]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize 114 // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_400]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize 115 // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.ubsantrap(i8 7){{.*}}, !nosanitize 116 // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize 117 // CHECK-SANITIZE: [[CONT]]: 118 // CHECK-NEXT: ret i8 %[[DST]] 119 // CHECK-NEXT: } 120 #line 400 121 return src; 122 } 123 124 // CHECK-LABEL: @unsigned_char_to_signed_char 125 // CHECK-SAME: (i8 noundef zeroext %[[SRC:.*]]) 126 signed char unsigned_char_to_signed_char(unsigned char src) { 127 // CHECK: %[[SRC_ADDR:.*]] = alloca i8 128 // CHECK-NEXT: store i8 %[[SRC]], i8* %[[SRC_ADDR]] 129 // CHECK-NEXT: %[[DST:.*]] = load i8, i8* %[[SRC_ADDR]] 130 // CHECK-SANITIZE-NEXT: %[[DST_NEGATIVITYCHECK:.*]] = icmp slt i8 %[[DST]], 0, !nosanitize 131 // CHECK-SANITIZE-NEXT: %[[SIGNCHANGECHECK:.*]] = icmp eq i1 false, %[[DST_NEGATIVITYCHECK]], !nosanitize 132 // CHECK-SANITIZE-NEXT: br i1 %[[SIGNCHANGECHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize 133 // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]: 134 // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i8 %[[DST]] to i64, !nosanitize 135 // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize 136 // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_500]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize 137 // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_500]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize 138 // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.ubsantrap(i8 7){{.*}}, !nosanitize 139 // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize 140 // CHECK-SANITIZE: [[CONT]]: 141 // CHECK-NEXT: ret i8 %[[DST]] 142 // CHECK-NEXT: } 143 #line 500 144 return src; 145 } 146 147 // CHECK-LABEL: @signed_char_to_unsigned_int 148 // CHECK-SAME: (i8 noundef signext %[[SRC:.*]]) 149 unsigned int signed_char_to_unsigned_int(signed char src) { 150 // CHECK: %[[SRC_ADDR:.*]] = alloca i8 151 // CHECK-NEXT: store i8 %[[SRC]], i8* %[[SRC_ADDR]] 152 // CHECK-NEXT: %[[DST:.*]] = load i8, i8* %[[SRC_ADDR]] 153 // CHECK-NEXT: %[[CONV:.*]] = sext i8 %[[DST]] to i32 154 // CHECK-SANITIZE-NEXT: %[[SRC_NEGATIVITYCHECK:.*]] = icmp slt i8 %[[DST]], 0, !nosanitize 155 // CHECK-SANITIZE-NEXT: %[[SIGNCHANGECHECK:.*]] = icmp eq i1 %[[SRC_NEGATIVITYCHECK]], false, !nosanitize 156 // CHECK-SANITIZE-NEXT: br i1 %[[SIGNCHANGECHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize 157 // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]: 158 // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i8 %[[DST]] to i64, !nosanitize 159 // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTCONV:.*]] = zext i32 %[[CONV]] to i64, !nosanitize 160 // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_600]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTCONV]]){{.*}}, !nosanitize 161 // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_600]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTCONV]]){{.*}}, !nosanitize 162 // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.ubsantrap(i8 7){{.*}}, !nosanitize 163 // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize 164 // CHECK-SANITIZE: [[CONT]]: 165 // CHECK-NEXT: ret i32 %[[CONV]] 166 // CHECK-NEXT: } 167 #line 600 168 return src; 169 } 170 171 // This one result (after optimizations) in 'icmp sge i8 (trunc i32 %src), 0' 172 173 // CHECK-LABEL: @unsigned_int_to_signed_char 174 // CHECK-SAME: i32 noundef %[[SRC:.*]]) 175 signed char unsigned_int_to_signed_char(unsigned int src) { 176 // CHECK: %[[SRC_ADDR:.*]] = alloca i32 177 // CHECK-NEXT: store i32 %[[SRC]], i32* %[[SRC_ADDR]] 178 // CHECK-NEXT: %[[DST:.*]] = load i32, i32* %[[SRC_ADDR]] 179 // CHECK-NEXT: %[[CONV:.*]] = trunc i32 %[[DST]] to i8 180 // CHECK-SANITIZE-NEXT: %[[DST_NEGATIVITYCHECK:.*]] = icmp slt i8 %[[CONV]], 0, !nosanitize 181 // CHECK-SANITIZE-NEXT: %[[SIGNCHANGECHECK:.*]] = icmp eq i1 false, %[[DST_NEGATIVITYCHECK]], !nosanitize 182 // CHECK-SANITIZE-NEXT: br i1 %[[SIGNCHANGECHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize 183 // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]: 184 // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[DST]] to i64, !nosanitize 185 // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTCONV:.*]] = zext i8 %[[CONV]] to i64, !nosanitize 186 // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_700]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTCONV]]){{.*}}, !nosanitize 187 // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_700]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTCONV]]){{.*}}, !nosanitize 188 // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.ubsantrap(i8 7){{.*}}, !nosanitize 189 // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize 190 // CHECK-SANITIZE: [[CONT]]: 191 // CHECK-NEXT: ret i8 %[[CONV]] 192 // CHECK-NEXT: } 193 #line 700 194 return src; 195 } 196 197 // The worst one: 'xor i1 (icmp sge i8 (trunc i32 %x), 0), (icmp sge i32 %x, 0)' 198 199 // CHECK-LABEL: @signed_int_to_signed_char 200 // CHECK-SAME: i32 noundef %[[SRC:.*]]) 201 signed char signed_int_to_signed_char(signed int x) { 202 // CHECK: %[[SRC_ADDR:.*]] = alloca i32 203 // CHECK-NEXT: store i32 %[[SRC]], i32* %[[SRC_ADDR]] 204 // CHECK-NEXT: %[[DST:.*]] = load i32, i32* %[[SRC_ADDR]] 205 // CHECK-NEXT: %[[CONV:.*]] = trunc i32 %[[DST]] to i8 206 // CHECK-SANITIZE-NEXT: %[[SRC_NEGATIVITYCHECK:.*]] = icmp slt i32 %[[DST]], 0, !nosanitize 207 // CHECK-SANITIZE-NEXT: %[[DST_NEGATIVITYCHECK:.*]] = icmp slt i8 %[[CONV]], 0, !nosanitize 208 // CHECK-SANITIZE-NEXT: %[[SIGNCHANGECHECK:.*]] = icmp eq i1 %[[SRC_NEGATIVITYCHECK]], %[[DST_NEGATIVITYCHECK]], !nosanitize 209 // CHECK-SANITIZE-NEXT: br i1 %[[SIGNCHANGECHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize 210 // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]: 211 // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[DST]] to i64, !nosanitize 212 // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTCONV:.*]] = zext i8 %[[CONV]] to i64, !nosanitize 213 // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_800]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTCONV]]){{.*}}, !nosanitize 214 // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_800]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTCONV]]){{.*}}, !nosanitize 215 // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.ubsantrap(i8 7){{.*}}, !nosanitize 216 // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize 217 // CHECK-SANITIZE: [[CONT]]: 218 // CHECK-NEXT: ret i8 %[[CONV]] 219 // CHECK-NEXT: } 220 #line 800 221 return x; 222 } 223 224 // ========================================================================== // 225 // Check canonical type stuff 226 // ========================================================================== // 227 228 typedef unsigned int uint32_t; 229 typedef signed int int32_t; 230 231 // CHECK-LABEL: @uint32_t_to_int32_t 232 // CHECK-SAME: i32 noundef %[[SRC:.*]]) 233 int32_t uint32_t_to_int32_t(uint32_t src) { 234 // CHECK: %[[SRC_ADDR:.*]] = alloca i32 235 // CHECK-NEXT: store i32 %[[SRC]], i32* %[[SRC_ADDR]] 236 // CHECK-NEXT: %[[DST:.*]] = load i32, i32* %[[SRC_ADDR]] 237 // CHECK-SANITIZE-NEXT: %[[DST_NEGATIVITYCHECK:.*]] = icmp slt i32 %[[DST]], 0, !nosanitize 238 // CHECK-SANITIZE-NEXT: %[[SIGNCHANGECHECK:.*]] = icmp eq i1 false, %[[DST_NEGATIVITYCHECK]], !nosanitize 239 // CHECK-SANITIZE-NEXT: br i1 %[[SIGNCHANGECHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize 240 // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]: 241 // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[DST]] to i64, !nosanitize 242 // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i32 %[[DST]] to i64, !nosanitize 243 // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_900]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize 244 // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_900]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize 245 // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.ubsantrap(i8 7){{.*}}, !nosanitize 246 // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize 247 // CHECK-SANITIZE: [[CONT]]: 248 // CHECK-NEXT: ret i32 %[[DST]] 249 // CHECK-NEXT: } 250 #line 900 251 return src; 252 } 253 254 // ========================================================================== // 255 // Check that explicit conversion does not interfere with implicit conversion 256 // ========================================================================== // 257 // These contain one implicit and one explicit sign-changing conversion. 258 // We want to make sure that we still diagnose the implicit conversion. 259 260 // Implicit sign-change after explicit sign-change. 261 // CHECK-LABEL: @explicit_conversion_interference0 262 unsigned int explicit_conversion_interference0(unsigned int c) { 263 // CHECK-SANITIZE: call 264 return (signed int)c; 265 } 266 267 // Implicit sign-change before explicit sign-change. 268 // CHECK-LABEL: @explicit_conversion_interference1 269 unsigned int explicit_conversion_interference1(unsigned int c) { 270 // CHECK-SANITIZE: call 271 signed int b; 272 return (unsigned int)(b = c); 273 } 274