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