1 // RUN: %clang_cc1 -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s --check-prefix=CHECK
2 // RUN: %clang_cc1 -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 -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 -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
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 }, ptr @[[UNSIGNED_INT]], ptr @[[SIGNED_INT]], i8 3 }
9 // CHECK-SANITIZE-ANYRECOVER-NEXT: @[[LINE_200:.*]] = {{.*}}, i32 200, i32 10 }, ptr @[[SIGNED_INT]], ptr @[[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 }, ptr @[[SIGNED_INT]], ptr @[[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 }, ptr @[[SIGNED_CHAR]], ptr @[[UNSIGNED_CHAR]], i8 3 }
14 // CHECK-SANITIZE-ANYRECOVER-NEXT: @[[LINE_500:.*]] = {{.*}}, i32 500, i32 10 }, ptr @[[UNSIGNED_CHAR]], ptr @[[SIGNED_CHAR]], i8 3 }
15 // CHECK-SANITIZE-ANYRECOVER-NEXT: @[[LINE_600:.*]] = {{.*}}, i32 600, i32 10 }, ptr @[[SIGNED_CHAR]], ptr @[[UNSIGNED_INT]], i8 3 }
16 // CHECK-SANITIZE-ANYRECOVER-NEXT: @[[LINE_700:.*]] = {{.*}}, i32 700, i32 10 }, ptr @[[UNSIGNED_INT]], ptr @[[SIGNED_CHAR]], i8 3 }
17 // CHECK-SANITIZE-ANYRECOVER-NEXT: @[[LINE_800:.*]] = {{.*}}, i32 800, i32 10 }, ptr @[[SIGNED_INT]], ptr @[[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 }, ptr @[[UINT32]], ptr @[[INT32]], i8 3 }
22 // ========================================================================== //
23 // The expected true-positives.
24 // These are implicit, potentially sign-altering, conversions.
25 // ========================================================================== //
27 // These 3 result (after optimizations) in simple 'icmp sge i32 %src, 0'.
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]], ptr %[[SRC_ADDR]]
34 // CHECK-NEXT: %[[DST:.*]] = load i32, ptr %[[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(ptr @[[LINE_100]], i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
42 // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(ptr @[[LINE_100]], 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]]
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]], ptr %[[SRC_ADDR]]
57 // CHECK-NEXT: %[[DST:.*]] = load i32, ptr %[[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(ptr @[[LINE_200]], i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
65 // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(ptr @[[LINE_200]], 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]]
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]], ptr %[[SRC_ADDR]]
80 // CHECK-NEXT: %[[DST:.*]] = load i32, ptr %[[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(ptr @[[LINE_300]], i64 %[[EXTSRC]], i64 %[[EXTCONV]]){{.*}}, !nosanitize
89 // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(ptr @[[LINE_300]], 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]]
99 // These 3 result (after optimizations) in simple 'icmp sge i8 %src, 0'
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]], ptr %[[SRC_ADDR]]
106 // CHECK-NEXT: %[[DST:.*]] = load i8, ptr %[[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(ptr @[[LINE_400]], i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
114 // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(ptr @[[LINE_400]], 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]]
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]], ptr %[[SRC_ADDR]]
129 // CHECK-NEXT: %[[DST:.*]] = load i8, ptr %[[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(ptr @[[LINE_500]], i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
137 // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(ptr @[[LINE_500]], 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]]
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]], ptr %[[SRC_ADDR]]
152 // CHECK-NEXT: %[[DST:.*]] = load i8, ptr %[[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(ptr @[[LINE_600]], i64 %[[EXTSRC]], i64 %[[EXTCONV]]){{.*}}, !nosanitize
161 // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(ptr @[[LINE_600]], 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]]
171 // This one result (after optimizations) in 'icmp sge i8 (trunc i32 %src), 0'
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]], ptr %[[SRC_ADDR]]
178 // CHECK-NEXT: %[[DST:.*]] = load i32, ptr %[[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(ptr @[[LINE_700]], i64 %[[EXTSRC]], i64 %[[EXTCONV]]){{.*}}, !nosanitize
187 // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(ptr @[[LINE_700]], 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]]
197 // The worst one: 'xor i1 (icmp sge i8 (trunc i32 %x), 0), (icmp sge i32 %x, 0)'
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]], ptr %[[SRC_ADDR]]
204 // CHECK-NEXT: %[[DST:.*]] = load i32, ptr %[[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(ptr @[[LINE_800]], i64 %[[EXTSRC]], i64 %[[EXTCONV]]){{.*}}, !nosanitize
214 // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(ptr @[[LINE_800]], 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]]
224 // ========================================================================== //
225 // Check canonical type stuff
226 // ========================================================================== //
228 typedef unsigned int uint32_t;
229 typedef signed int int32_t;
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]], ptr %[[SRC_ADDR]]
236 // CHECK-NEXT: %[[DST:.*]] = load i32, ptr %[[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(ptr @[[LINE_900]], i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
244 // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(ptr @[[LINE_900]], 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]]
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.
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
;
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
272 return (unsigned int)(b
= c
);