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