1 // RUN: %check_clang_tidy %s bugprone-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 [bugprone-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