150
|
1 // RUN: %clang_cc1 -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s --check-prefix=CHECK
|
|
2 // 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
|
|
5
|
|
6 extern "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
|
|
16 unsigned 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
|
|
26 unsigned 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
|
|
43 unsigned 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
|
|
50 unsigned 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
|
|
57 signed 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
|
|
64 signed 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
|
|
74 unsigned 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
|
|
81 signed 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
|
|
88 unsigned 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
|
|
95 signed 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
|
|
104 using UnsignedChar = unsigned char;
|
|
105 using SignedChar = signed char;
|
|
106 using UnsignedInt = unsigned int;
|
|
107 using SignedInt = signed int;
|
|
108
|
|
109 // CHECK-LABEL: @explicit_functional_unsigned_int_to_unsigned_char
|
|
110 unsigned 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
|
|
117 unsigned 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
|
|
124 signed 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
|
|
131 signed 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
|
|
141 unsigned 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
|
|
148 signed 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
|
|
155 unsigned 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
|
|
162 signed 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
|
|
172 unsigned 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
|
|
179 unsigned 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
|
|
186 signed 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
|
|
193 signed 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
|
|
203 unsigned 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
|
|
210 signed 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
|
|
217 unsigned 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
|
|
224 signed 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
|
|
237 template <typename a>
|
|
238 a b(a c, const a &d) {
|
|
239 if (d)
|
|
240 ;
|
|
241 return c;
|
|
242 }
|
|
243
|
|
244 extern "C" { // Disable name mangling.
|
|
245
|
|
246 // CHECK-LABEL: @false_positive_with_MaterializeTemporaryExpr
|
|
247 int 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"
|