Clang Project

clang_source_code/test/CodeGen/catch-implicit-integer-sign-changes.c
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
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 %[[SRC:.*]])
31signed 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.trap(){{.*}}, !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 %[[SRC:.*]])
54unsigned 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.trap(){{.*}}, !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 %[[SRC:.*]])
77unsigned 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.trap(){{.*}}, !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 signext %[[SRC:.*]])
103unsigned 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.trap(){{.*}}, !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 zeroext %[[SRC:.*]])
126signed 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.trap(){{.*}}, !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 signext %[[SRC:.*]])
149unsigned 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.trap(){{.*}}, !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 %[[SRC:.*]])
175signed 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.trap(){{.*}}, !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 %[[SRC:.*]])
201signed 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.trap(){{.*}}, !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
228typedef unsigned int uint32_t;
229typedef signed int int32_t;
230
231// CHECK-LABEL: @uint32_t_to_int32_t
232// CHECK-SAME: (i32 %[[SRC:.*]])
233int32_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.trap(){{.*}}, !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
262unsigned 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
269unsigned int explicit_conversion_interference1(unsigned int c) {
270  // CHECK-SANITIZE: call
271  signed int b;
272  return (unsigned int)(b = c);
273}
274