1 | // RUN: %clang_cc1 -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s -implicit-check-not="call void @__ubsan_handle_implicit_conversion" --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 |
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 |
5 | |
6 | // ========================================================================== // |
7 | // The expected true-negatives. |
8 | // ========================================================================== // |
9 | |
10 | // Sanitization is explicitly disabled. |
11 | // ========================================================================== // |
12 | |
13 | // CHECK-LABEL: @blacklist_0 |
14 | __attribute__((no_sanitize("undefined"))) unsigned int blacklist_0(signed int src) { |
15 | // We are not in "undefined" group, so that doesn't work. |
16 | // CHECK-SANITIZE: call |
17 | return src; |
18 | } |
19 | |
20 | // CHECK-LABEL: @blacklist_1 |
21 | __attribute__((no_sanitize("integer"))) unsigned int blacklist_1(signed int src) { |
22 | return src; |
23 | } |
24 | |
25 | // CHECK-LABEL: @blacklist_2 |
26 | __attribute__((no_sanitize("implicit-conversion"))) unsigned int blacklist_2(signed int src) { |
27 | return src; |
28 | } |
29 | |
30 | // CHECK-LABEL: @blacklist_3 |
31 | __attribute__((no_sanitize("implicit-integer-sign-change"))) unsigned int blacklist_3(signed int src) { |
32 | return src; |
33 | } |
34 | |
35 | // Explicit sign-changing conversions. |
36 | // ========================================================================== // |
37 | |
38 | // CHECK-LABEL: explicit_signed_int_to_unsigned_int |
39 | unsigned int explicit_signed_int_to_unsigned_int(signed int src) { |
40 | return (unsigned int)src; |
41 | } |
42 | |
43 | // CHECK-LABEL: explicit_unsigned_int_to_signed_int |
44 | signed int explicit_unsigned_int_to_signed_int(unsigned int src) { |
45 | return (signed int)src; |
46 | } |
47 | |
48 | // Explicit NOP conversions. |
49 | // ========================================================================== // |
50 | |
51 | // CHECK-LABEL: @explicit_ununsigned_int_to_ununsigned_int |
52 | unsigned int explicit_ununsigned_int_to_ununsigned_int(unsigned int src) { |
53 | return (unsigned int)src; |
54 | } |
55 | |
56 | // CHECK-LABEL: @explicit_unsigned_int_to_unsigned_int |
57 | signed int explicit_unsigned_int_to_unsigned_int(signed int src) { |
58 | return (signed int)src; |
59 | } |
60 | |
61 | // conversions to to boolean type are not counted as sign-change. |
62 | // ========================================================================== // |
63 | |
64 | // CHECK-LABEL: @unsigned_int_to_bool |
65 | _Bool unsigned_int_to_bool(unsigned int src) { |
66 | return src; |
67 | } |
68 | |
69 | // CHECK-LABEL: @signed_int_to_bool |
70 | _Bool signed_int_to_bool(signed int src) { |
71 | return src; |
72 | } |
73 | |
74 | // CHECK-LABEL: @explicit_unsigned_int_to_bool |
75 | _Bool explicit_unsigned_int_to_bool(unsigned int src) { |
76 | return (_Bool)src; |
77 | } |
78 | |
79 | // CHECK-LABEL: @explicit_signed_int_to_bool |
80 | _Bool explicit_signed_int_to_bool(signed int src) { |
81 | return (_Bool)src; |
82 | } |
83 | |
84 | // Explicit conversions from pointer to an integer. |
85 | // Can not have an implicit conversion from pointer to an integer. |
86 | // Can not have an implicit conversion between two enums. |
87 | // ========================================================================== // |
88 | |
89 | // CHECK-LABEL: @explicit_voidptr_to_unsigned_int |
90 | unsigned int explicit_voidptr_to_unsigned_int(void *src) { |
91 | return (unsigned int)src; |
92 | } |
93 | |
94 | // CHECK-LABEL: @explicit_voidptr_to_signed_int |
95 | signed int explicit_voidptr_to_signed_int(void *src) { |
96 | return (signed int)src; |
97 | } |
98 | |
99 | // Implicit conversions from floating-point. |
100 | // ========================================================================== // |
101 | |
102 | // CHECK-LABEL: @float_to_unsigned_int |
103 | unsigned int float_to_unsigned_int(float src) { |
104 | return src; |
105 | } |
106 | |
107 | // CHECK-LABEL: @float_to_signed_int |
108 | signed int float_to_signed_int(float src) { |
109 | return src; |
110 | } |
111 | |
112 | // CHECK-LABEL: @double_to_unsigned_int |
113 | unsigned int double_to_unsigned_int(double src) { |
114 | return src; |
115 | } |
116 | |
117 | // CHECK-LABEL: @double_to_signed_int |
118 | signed int double_to_signed_int(double src) { |
119 | return src; |
120 | } |
121 | |
122 | // Sugar. |
123 | // ========================================================================== // |
124 | |
125 | typedef unsigned int uint32_t; |
126 | |
127 | // CHECK-LABEL: @uint32_to_unsigned_int |
128 | unsigned int uint32_to_unsigned_int(uint32_t src) { |
129 | return src; |
130 | } |
131 | |
132 | // CHECK-LABEL: @unsigned_int_to_uint32 |
133 | uint32_t unsigned_int_to_uint32(unsigned int src) { |
134 | return src; |
135 | } |
136 | |
137 | // CHECK-LABEL: @uint32_to_uint32 |
138 | uint32_t uint32_to_uint32(uint32_t src) { |
139 | return src; |
140 | } |
141 | |
142 | // "Transparent" Enum. |
143 | // ========================================================================== // |
144 | |
145 | enum a { b = ~2147483647 }; |
146 | enum a c(); |
147 | void d(int); |
148 | void e(); |
149 | void e() { |
150 | enum a f = c(); |
151 | d(f); |
152 | } |
153 | |