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 | } |
274 | |