blob: 2902fe1e884da80f314dfe682712d6459cda9069 [file] [log] [blame]
Roman Lebedevb69ba222018-07-30 18:58:30 +00001// RUN: %clang_cc1 -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s --check-prefix=CHECK
Roman Lebedevdd403572018-10-11 09:09:50 +00002// RUN: %clang_cc1 -fsanitize=implicit-unsigned-integer-truncation,implicit-signed-integer-truncation -fno-sanitize-recover=implicit-unsigned-integer-truncation,implicit-signed-integer-truncation -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s --check-prefixes=CHECK,CHECK-SANITIZE,CHECK-SANITIZE-ANYRECOVER,CHECK-SANITIZE-NORECOVER
3// RUN: %clang_cc1 -fsanitize=implicit-unsigned-integer-truncation,implicit-signed-integer-truncation -fsanitize-recover=implicit-unsigned-integer-truncation,implicit-signed-integer-truncation -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s --check-prefixes=CHECK,CHECK-SANITIZE,CHECK-SANITIZE-ANYRECOVER,CHECK-SANITIZE-RECOVER
4// RUN: %clang_cc1 -fsanitize=implicit-unsigned-integer-truncation,implicit-signed-integer-truncation -fsanitize-trap=implicit-unsigned-integer-truncation,implicit-signed-integer-truncation -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s --check-prefixes=CHECK,CHECK-SANITIZE,CHECK-SANITIZE-TRAP
Roman Lebedevb69ba222018-07-30 18:58:30 +00005
6extern "C" { // Disable name mangling.
7
8// ========================================================================== //
9// Check that explicit cast does not interfere with implicit conversion
10// ========================================================================== //
11// These contain one implicit truncating conversion, and one explicit truncating cast.
12// We want to make sure that we still diagnose the implicit conversion.
13
14// Implicit truncation after explicit truncation.
15// CHECK-LABEL: @explicit_cast_interference0
16unsigned char explicit_cast_interference0(unsigned int c) {
17 // CHECK-SANITIZE: %[[ANYEXT:.*]] = zext i8 %[[DST:.*]] to i16, !nosanitize
18 // CHECK-SANITIZE: call
19 // CHECK-SANITIZE-NOT: call
20 // CHECK: }
21 return (unsigned short)c;
22}
23
24// Implicit truncation before explicit truncation.
25// CHECK-LABEL: @explicit_cast_interference1
26unsigned char explicit_cast_interference1(unsigned int c) {
27 // CHECK-SANITIZE: %[[ANYEXT:.*]] = zext i16 %[[DST:.*]] to i32, !nosanitize
28 // CHECK-SANITIZE: call
29 // CHECK-SANITIZE-NOT: call
30 // CHECK: }
31 unsigned short b;
32 return (unsigned char)(b = c);
33}
34
35// ========================================================================== //
36// The expected true-negatives.
37// ========================================================================== //
38
39// Explicit truncating casts.
40// ========================================================================== //
41
42// CHECK-LABEL: @explicit_unsigned_int_to_unsigned_char
43unsigned char explicit_unsigned_int_to_unsigned_char(unsigned int src) {
44 // CHECK-SANITIZE-NOT: call
45 // CHECK: }
46 return (unsigned char)src;
47}
48
49// CHECK-LABEL: @explicit_signed_int_to_unsigned_char
50unsigned char explicit_signed_int_to_unsigned_char(signed int src) {
51 // CHECK-SANITIZE-NOT: call
52 // CHECK: }
53 return (unsigned char)src;
54}
55
56// CHECK-LABEL: @explicit_unsigned_int_to_signed_char
57signed char explicit_unsigned_int_to_signed_char(unsigned int src) {
58 // CHECK-SANITIZE-NOT: call
59 // CHECK: }
60 return (signed char)src;
61}
62
63// CHECK-LABEL: @explicit_signed_int_to_signed_char
64signed char explicit_signed_int_to_signed_char(signed int src) {
65 // CHECK-SANITIZE-NOT: call
66 // CHECK: }
67 return (signed char)src;
68}
69
70// Explicit NOP casts.
71// ========================================================================== //
72
73// CHECK-LABEL: @explicit_unsigned_int_to_unsigned_int
74unsigned int explicit_unsigned_int_to_unsigned_int(unsigned int src) {
75 // CHECK-SANITIZE-NOT: call
76 // CHECK: }
77 return (unsigned int)src;
78}
79
80// CHECK-LABEL: @explicit_signed_int_to_signed_int
81signed int explicit_signed_int_to_signed_int(signed int src) {
82 // CHECK-SANITIZE-NOT: call
83 // CHECK: }
84 return (signed int)src;
85}
86
87// CHECK-LABEL: @explicit_unsigned_char_to_signed_char
88unsigned char explicit_unsigned_char_to_signed_char(unsigned char src) {
89 // CHECK-SANITIZE-NOT: call
90 // CHECK: }
91 return (unsigned char)src;
92}
93
94// CHECK-LABEL: @explicit_signed_char_to_signed_char
95signed char explicit_signed_char_to_signed_char(signed char src) {
96 // CHECK-SANITIZE-NOT: call
97 // CHECK: }
98 return (signed char)src;
99}
100
101// Explicit functional truncating casts.
102// ========================================================================== //
103
104using UnsignedChar = unsigned char;
105using SignedChar = signed char;
106using UnsignedInt = unsigned int;
107using SignedInt = signed int;
108
109// CHECK-LABEL: @explicit_functional_unsigned_int_to_unsigned_char
110unsigned char explicit_functional_unsigned_int_to_unsigned_char(unsigned int src) {
111 // CHECK-SANITIZE-NOT: call
112 // CHECK: }
113 return UnsignedChar(src);
114}
115
116// CHECK-LABEL: @explicit_functional_signed_int_to_unsigned_char
117unsigned char explicit_functional_signed_int_to_unsigned_char(signed int src) {
118 // CHECK-SANITIZE-NOT: call
119 // CHECK: }
120 return UnsignedChar(src);
121}
122
123// CHECK-LABEL: @explicit_functional_unsigned_int_to_signed_char
124signed char explicit_functional_unsigned_int_to_signed_char(unsigned int src) {
125 // CHECK-SANITIZE-NOT: call
126 // CHECK: }
127 return SignedChar(src);
128}
129
130// CHECK-LABEL: @explicit_functional_signed_int_to_signed_char
131signed char explicit_functional_signed_int_to_signed_char(signed int src) {
132 // CHECK-SANITIZE-NOT: call
133 // CHECK: }
134 return SignedChar(src);
135}
136
137// Explicit functional NOP casts.
138// ========================================================================== //
139
140// CHECK-LABEL: @explicit_functional_unsigned_int_to_unsigned_int
141unsigned int explicit_functional_unsigned_int_to_unsigned_int(unsigned int src) {
142 // CHECK-SANITIZE-NOT: call
143 // CHECK: }
144 return UnsignedInt(src);
145}
146
147// CHECK-LABEL: @explicit_functional_signed_int_to_signed_int
148signed int explicit_functional_signed_int_to_signed_int(signed int src) {
149 // CHECK-SANITIZE-NOT: call
150 // CHECK: }
151 return SignedInt(src);
152}
153
154// CHECK-LABEL: @explicit_functional_unsigned_char_to_signed_char
155unsigned char explicit_functional_unsigned_char_to_signed_char(unsigned char src) {
156 // CHECK-SANITIZE-NOT: call
157 // CHECK: }
158 return UnsignedChar(src);
159}
160
161// CHECK-LABEL: @explicit_functional_signed_char_to_signed_char
162signed char explicit_functional_signed_char_to_signed_char(signed char src) {
163 // CHECK-SANITIZE-NOT: call
164 // CHECK: }
165 return SignedChar(src);
166}
167
168// Explicit C++-style casts truncating casts.
169// ========================================================================== //
170
171// CHECK-LABEL: @explicit_cppstyleunsigned_int_to_unsigned_char
172unsigned char explicit_cppstyleunsigned_int_to_unsigned_char(unsigned int src) {
173 // CHECK-SANITIZE-NOT: call
174 // CHECK: }
175 return static_cast<unsigned char>(src);
176}
177
178// CHECK-LABEL: @explicit_cppstylesigned_int_to_unsigned_char
179unsigned char explicit_cppstylesigned_int_to_unsigned_char(signed int src) {
180 // CHECK-SANITIZE-NOT: call
181 // CHECK: }
182 return static_cast<unsigned char>(src);
183}
184
185// CHECK-LABEL: @explicit_cppstyleunsigned_int_to_signed_char
186signed char explicit_cppstyleunsigned_int_to_signed_char(unsigned int src) {
187 // CHECK-SANITIZE-NOT: call
188 // CHECK: }
189 return static_cast<signed char>(src);
190}
191
192// CHECK-LABEL: @explicit_cppstylesigned_int_to_signed_char
193signed char explicit_cppstylesigned_int_to_signed_char(signed int src) {
194 // CHECK-SANITIZE-NOT: call
195 // CHECK: }
196 return static_cast<signed char>(src);
197}
198
199// Explicit C++-style casts NOP casts.
200// ========================================================================== //
201
202// CHECK-LABEL: @explicit_cppstyleunsigned_int_to_unsigned_int
203unsigned int explicit_cppstyleunsigned_int_to_unsigned_int(unsigned int src) {
204 // CHECK-SANITIZE-NOT: call
205 // CHECK: }
206 return static_cast<unsigned int>(src);
207}
208
209// CHECK-LABEL: @explicit_cppstylesigned_int_to_signed_int
210signed int explicit_cppstylesigned_int_to_signed_int(signed int src) {
211 // CHECK-SANITIZE-NOT: call
212 // CHECK: }
213 return static_cast<signed int>(src);
214}
215
216// CHECK-LABEL: @explicit_cppstyleunsigned_char_to_signed_char
217unsigned char explicit_cppstyleunsigned_char_to_signed_char(unsigned char src) {
218 // CHECK-SANITIZE-NOT: call
219 // CHECK: }
220 return static_cast<unsigned char>(src);
221}
222
223// CHECK-LABEL: @explicit_cppstylesigned_char_to_signed_char
224signed char explicit_cppstylesigned_char_to_signed_char(signed char src) {
225 // CHECK-SANITIZE-NOT: call
226 // CHECK: }
227 return static_cast<signed char>(src);
228}
229
230} // extern "C"
231
232// ---------------------------------------------------------------------------//
233// A problematic true-negative involving simple C++ code.
234// The problem is tha the NoOp ExplicitCast is directly within MaterializeTemporaryExpr(),
235// so a special care is neeeded.
236// See https://reviews.llvm.org/D48958#1161345
237template <typename a>
238a b(a c, const a &d) {
239 if (d)
240 ;
241 return c;
242}
243
244extern "C" { // Disable name mangling.
245
246// CHECK-LABEL: @false_positive_with_MaterializeTemporaryExpr
247int false_positive_with_MaterializeTemporaryExpr() {
248 // CHECK-SANITIZE-NOT: call{{.*}}ubsan
249 // CHECK: }
250 int e = b<unsigned>(4, static_cast<unsigned>(4294967296));
251 return e;
252}
253
254// ---------------------------------------------------------------------------//
255
256} // extern "C"