1 | // RUN: %check_clang_tidy %s cppcoreguidelines-narrowing-conversions %t \ |
2 | // RUN: -std=c++17 -- -target x86_64-unknown-linux |
3 | |
4 | #define CHAR_BITS 8 |
5 | static_assert(sizeof(unsigned int) == 32 / CHAR_BITS); |
6 | |
7 | template <typename T, typename U> |
8 | struct is_same { |
9 | static constexpr bool value = false; |
10 | }; |
11 | template <typename T> |
12 | struct is_same<T, T> { |
13 | static constexpr bool value = true; |
14 | }; |
15 | |
16 | template <typename T, typename U> |
17 | static constexpr bool is_same_v = is_same<T, U>::value; |
18 | |
19 | struct NoBitfield { |
20 | unsigned int id; |
21 | }; |
22 | struct SmallBitfield { |
23 | unsigned int id : 4; |
24 | }; |
25 | |
26 | struct BigBitfield { |
27 | unsigned int id : 31; |
28 | }; |
29 | struct CompleteBitfield { |
30 | unsigned int id : 32; |
31 | }; |
32 | |
33 | int example_warning(unsigned x) { |
34 | // CHECK-MESSAGES: :[[@LINE+1]]:10: warning: narrowing conversion from 'unsigned int' to signed type 'int' is implementation-defined [cppcoreguidelines-narrowing-conversions] |
35 | return x; |
36 | } |
37 | |
38 | void test_binary_and(SmallBitfield x) { |
39 | static_assert(is_same_v<decltype(x.id & 1), int>); |
40 | static_assert(is_same_v<decltype(x.id & 1u), unsigned>); |
41 | |
42 | x.id & 1; |
43 | x.id & 1u; |
44 | |
45 | 1 & x.id; |
46 | 1u & x.id; |
47 | } |
48 | |
49 | void test_binary_or(SmallBitfield x) { |
50 | static_assert(is_same_v<decltype(x.id | 1), int>); |
51 | static_assert(is_same_v<decltype(x.id | 1u), unsigned>); |
52 | |
53 | x.id | 1; |
54 | x.id | 1u; |
55 | |
56 | 1 | x.id; |
57 | 1u | x.id; |
58 | } |
59 | |
60 | template <typename T> |
61 | void take(T); |
62 | |
63 | void test_parameter_passing(NoBitfield x) { |
64 | take<char>(x.id); |
65 | // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: narrowing conversion from 'unsigned int' to signed type 'char' is implementation-defined |
66 | take<short>(x.id); |
67 | // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: narrowing conversion from 'unsigned int' to signed type 'short' is implementation-defined |
68 | take<unsigned>(x.id); |
69 | take<int>(x.id); |
70 | // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: narrowing conversion from 'unsigned int' to signed type 'int' is implementation-defined |
71 | take<long>(x.id); |
72 | take<long long>(x.id); |
73 | } |
74 | |
75 | void test_parameter_passing(SmallBitfield x) { |
76 | take<char>(x.id); |
77 | // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: narrowing conversion from 'unsigned int' to signed type 'char' is implementation-defined |
78 | take<short>(x.id); |
79 | // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: narrowing conversion from 'unsigned int' to signed type 'short' is implementation-defined |
80 | take<unsigned>(x.id); |
81 | take<int>(x.id); // no-warning |
82 | take<long>(x.id); |
83 | take<long long>(x.id); |
84 | } |
85 | |
86 | void test_parameter_passing(BigBitfield x) { |
87 | take<char>(x.id); |
88 | // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: narrowing conversion from 'unsigned int' to signed type 'char' is implementation-defined |
89 | take<short>(x.id); |
90 | // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: narrowing conversion from 'unsigned int' to signed type 'short' is implementation-defined |
91 | take<unsigned>(x.id); |
92 | take<int>(x.id); // no-warning |
93 | take<long>(x.id); |
94 | take<long long>(x.id); |
95 | } |
96 | |
97 | void test_parameter_passing(CompleteBitfield x) { |
98 | take<char>(x.id); |
99 | // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: narrowing conversion from 'unsigned int' to signed type 'char' is implementation-defined |
100 | take<short>(x.id); |
101 | // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: narrowing conversion from 'unsigned int' to signed type 'short' is implementation-defined |
102 | take<unsigned>(x.id); |
103 | take<int>(x.id); |
104 | // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: narrowing conversion from 'unsigned int' to signed type 'int' is implementation-defined |
105 | take<long>(x.id); |
106 | take<long long>(x.id); |
107 | } |
108 | |
109 | void test(NoBitfield x) { |
110 | static_assert(is_same_v<decltype(x.id << 1), unsigned>); |
111 | static_assert(is_same_v<decltype(x.id << 1u), unsigned>); |
112 | static_assert(is_same_v<decltype(x.id + 1), unsigned>); |
113 | static_assert(is_same_v<decltype(x.id + 1u), unsigned>); |
114 | |
115 | x.id << 1; |
116 | x.id << 1u; |
117 | x.id >> 1; |
118 | x.id >> 1u; |
119 | x.id + 1; |
120 | x.id + 1u; |
121 | |
122 | 1 << x.id; |
123 | 1u << x.id; |
124 | 1 >> x.id; |
125 | 1u >> x.id; |
126 | 1 + x.id; |
127 | 1u + x.id; |
128 | } |
129 | |
130 | void test(SmallBitfield x) { |
131 | static_assert(is_same_v<decltype(x.id << 1), int>); |
132 | static_assert(is_same_v<decltype(x.id << 1u), int>); |
133 | |
134 | x.id << 1; |
135 | x.id << 1u; |
136 | x.id >> 1; |
137 | x.id >> 1u; |
138 | |
139 | x.id + 1; |
140 | x.id + 1u; |
141 | |
142 | 1 << x.id; |
143 | 1u << x.id; |
144 | 1 >> x.id; |
145 | 1u >> x.id; |
146 | |
147 | 1 + x.id; |
148 | 1u + x.id; |
149 | } |
150 | |
151 | void test(BigBitfield x) { |
152 | static_assert(is_same_v<decltype(x.id << 1), int>); |
153 | static_assert(is_same_v<decltype(x.id << 1u), int>); |
154 | |
155 | x.id << 1; |
156 | x.id << 1u; |
157 | x.id >> 1; |
158 | x.id >> 1u; |
159 | |
160 | x.id + 1; |
161 | x.id + 1u; |
162 | |
163 | 1 << x.id; |
164 | 1u << x.id; |
165 | 1 >> x.id; |
166 | 1u >> x.id; |
167 | |
168 | 1 + x.id; |
169 | 1u + x.id; |
170 | } |
171 | |
172 | void test(CompleteBitfield x) { |
173 | static_assert(is_same_v<decltype(x.id << 1), unsigned>); |
174 | static_assert(is_same_v<decltype(x.id << 1u), unsigned>); |
175 | |
176 | x.id << 1; |
177 | x.id << 1u; |
178 | x.id >> 1; |
179 | x.id >> 1u; |
180 | |
181 | x.id + 1; |
182 | x.id + 1u; |
183 | |
184 | 1 << x.id; |
185 | 1u << x.id; |
186 | 1 >> x.id; |
187 | 1u >> x.id; |
188 | |
189 | 1 + x.id; |
190 | 1u + x.id; |
191 | } |
192 | |
193 | void test_parens(SmallBitfield x) { |
194 | static_assert(is_same_v<decltype(x.id << (2)), int>); |
195 | static_assert(is_same_v<decltype(((x.id)) << (2)), int>); |
196 | x.id << (2); |
197 | ((x.id)) << (2); |
198 | |
199 | static_assert(is_same_v<decltype((2) << x.id), int>); |
200 | static_assert(is_same_v<decltype((2) << ((x.id))), int>); |
201 | (2) << x.id; |
202 | (2) << ((x.id)); |
203 | } |
204 | |