]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - test/CodeGen/catch-implicit-integer-sign-changes.c
Vendor import of clang trunk r351319 (just before the release_80 branch
[FreeBSD/FreeBSD.git] / 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:.*]])
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.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:.*]])
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.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:.*]])
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.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:.*]])
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.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:.*]])
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.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:.*]])
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.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:.*]])
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.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:.*]])
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.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
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 %[[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.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
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 }