xref: /llvm-project/clang-tools-extra/test/clang-tidy/checkers/bugprone/narrowing-conversions.cpp (revision e45e091b90896023584b303539bd8ae16d8932b3)
1*e45e091bSCongcong Cai // RUN: %check_clang_tidy %s bugprone-narrowing-conversions %t \
2*e45e091bSCongcong Cai // RUN: -config="{CheckOptions: { \
3*e45e091bSCongcong Cai // RUN:   bugprone-narrowing-conversions.WarnOnFloatingPointNarrowingConversion: false}}" \
4*e45e091bSCongcong Cai // RUN: -- -target x86_64-unknown-linux -fsigned-char
5*e45e091bSCongcong Cai 
6*e45e091bSCongcong Cai float ceil(float);
7*e45e091bSCongcong Cai namespace std {
8*e45e091bSCongcong Cai double ceil(double);
9*e45e091bSCongcong Cai long double floor(long double);
10*e45e091bSCongcong Cai } // namespace std
11*e45e091bSCongcong Cai 
12*e45e091bSCongcong Cai namespace floats {
13*e45e091bSCongcong Cai 
14*e45e091bSCongcong Cai struct ConvertsToFloat {
15*e45e091bSCongcong Cai   operator float() const { return 0.5f; }
16*e45e091bSCongcong Cai };
17*e45e091bSCongcong Cai 
18*e45e091bSCongcong Cai float operator"" _float(unsigned long long);
19*e45e091bSCongcong Cai 
20*e45e091bSCongcong Cai void narrow_fp_to_int_not_ok(double d) {
21*e45e091bSCongcong Cai   int i = 0;
22*e45e091bSCongcong Cai   i = d;
23*e45e091bSCongcong Cai   // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'double' to 'int' [bugprone-narrowing-conversions]
24*e45e091bSCongcong Cai   i = 0.5f;
25*e45e091bSCongcong Cai   // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from constant 'float' to 'int' [bugprone-narrowing-conversions]
26*e45e091bSCongcong Cai   i = static_cast<float>(d);
27*e45e091bSCongcong Cai   // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'float' to 'int' [bugprone-narrowing-conversions]
28*e45e091bSCongcong Cai   i = ConvertsToFloat();
29*e45e091bSCongcong Cai   // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'float' to 'int' [bugprone-narrowing-conversions]
30*e45e091bSCongcong Cai   i = 15_float;
31*e45e091bSCongcong Cai   // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'float' to 'int' [bugprone-narrowing-conversions]
32*e45e091bSCongcong Cai   i += d;
33*e45e091bSCongcong Cai   // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: narrowing conversion from 'double' to 'int' [bugprone-narrowing-conversions]
34*e45e091bSCongcong Cai   i += 0.5;
35*e45e091bSCongcong Cai   // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: narrowing conversion from constant 'double' to 'int' [bugprone-narrowing-conversions]
36*e45e091bSCongcong Cai   i += 0.5f;
37*e45e091bSCongcong Cai   // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: narrowing conversion from constant 'float' to 'int' [bugprone-narrowing-conversions]
38*e45e091bSCongcong Cai   i *= 0.5f;
39*e45e091bSCongcong Cai   // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: narrowing conversion from constant 'float' to 'int' [bugprone-narrowing-conversions]
40*e45e091bSCongcong Cai   i /= 0.5f;
41*e45e091bSCongcong Cai   // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: narrowing conversion from constant 'float' to 'int' [bugprone-narrowing-conversions]
42*e45e091bSCongcong Cai   i += (double)0.5f;
43*e45e091bSCongcong Cai   // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: narrowing conversion from constant 'double' to 'int' [bugprone-narrowing-conversions]
44*e45e091bSCongcong Cai   i += 2.0;
45*e45e091bSCongcong Cai   i += 2.0f;
46*e45e091bSCongcong Cai }
47*e45e091bSCongcong Cai 
48*e45e091bSCongcong Cai double operator"" _double(unsigned long long);
49*e45e091bSCongcong Cai 
50*e45e091bSCongcong Cai float narrow_double_to_float_return() {
51*e45e091bSCongcong Cai   return 0.5; // [dcl.init.list] 7.2 : in-range fp constant to narrower float is not a narrowing.
52*e45e091bSCongcong Cai }
53*e45e091bSCongcong Cai 
54*e45e091bSCongcong Cai void narrow_double_to_float_ok(double d) {
55*e45e091bSCongcong Cai   float f;
56*e45e091bSCongcong Cai   f = d;
57*e45e091bSCongcong Cai   f = 15_double;
58*e45e091bSCongcong Cai }
59*e45e091bSCongcong Cai 
60*e45e091bSCongcong Cai void narrow_fp_constants() {
61*e45e091bSCongcong Cai   float f;
62*e45e091bSCongcong Cai   f = 0.5; // [dcl.init.list] 7.2 : in-range fp constant to narrower float is not a narrowing.
63*e45e091bSCongcong Cai 
64*e45e091bSCongcong Cai   f = __builtin_huge_valf();  // max float is not narrowing.
65*e45e091bSCongcong Cai   f = -__builtin_huge_valf(); // -max float is not narrowing.
66*e45e091bSCongcong Cai   f = __builtin_inff();       // float infinity is not narrowing.
67*e45e091bSCongcong Cai   f = __builtin_nanf("0");    // float NaN is not narrowing.
68*e45e091bSCongcong Cai 
69*e45e091bSCongcong Cai   f = __builtin_huge_val();  // max double is not within-range of float.
70*e45e091bSCongcong Cai   f = -__builtin_huge_val(); // -max double is not within-range of float.
71*e45e091bSCongcong Cai   f = __builtin_inf();       // double infinity is not within-range of float.
72*e45e091bSCongcong Cai   f = __builtin_nan("0");    // double NaN is not narrowing.
73*e45e091bSCongcong Cai }
74*e45e091bSCongcong Cai 
75*e45e091bSCongcong Cai void narrow_double_to_float_not_ok_binary_ops(double d) {
76*e45e091bSCongcong Cai   float f;
77*e45e091bSCongcong Cai   f += 0.5;          // [dcl.init.list] 7.2 : in-range fp constant to narrower float is not a narrowing.
78*e45e091bSCongcong Cai   f += 2.0;          // [dcl.init.list] 7.2 : in-range fp constant to narrower float is not a narrowing.
79*e45e091bSCongcong Cai   f *= 0.5;          // [dcl.init.list] 7.2 : in-range fp constant to narrower float is not a narrowing.
80*e45e091bSCongcong Cai   f /= 0.5;          // [dcl.init.list] 7.2 : in-range fp constant to narrower float is not a narrowing.
81*e45e091bSCongcong Cai   f += (double)0.5f; // [dcl.init.list] 7.2 : in-range fp constant to narrower float is not a narrowing.
82*e45e091bSCongcong Cai   f += d;            // We do not warn about floating point narrowing by default.
83*e45e091bSCongcong Cai }
84*e45e091bSCongcong Cai 
85*e45e091bSCongcong Cai void narrow_fp_constant_to_bool_not_ok() {
86*e45e091bSCongcong Cai   bool b1 = 1.0;
87*e45e091bSCongcong Cai   // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: narrowing conversion from constant 'double' to 'bool' [bugprone-narrowing-conversions]
88*e45e091bSCongcong Cai   bool b2 = 1.0f;
89*e45e091bSCongcong Cai   // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: narrowing conversion from constant 'float' to 'bool' [bugprone-narrowing-conversions]
90*e45e091bSCongcong Cai }
91*e45e091bSCongcong Cai 
92*e45e091bSCongcong Cai void narrow_integer_to_floating() {
93*e45e091bSCongcong Cai   {
94*e45e091bSCongcong Cai     long long ll; // 64 bits
95*e45e091bSCongcong Cai     float f = ll; // doesn't fit in 24 bits
96*e45e091bSCongcong Cai     // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: narrowing conversion from 'long long' to 'float' [bugprone-narrowing-conversions]
97*e45e091bSCongcong Cai     double d = ll; // doesn't fit in 53 bits.
98*e45e091bSCongcong Cai     // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: narrowing conversion from 'long long' to 'double' [bugprone-narrowing-conversions]
99*e45e091bSCongcong Cai   }
100*e45e091bSCongcong Cai   {
101*e45e091bSCongcong Cai     int i;       // 32 bits
102*e45e091bSCongcong Cai     float f = i; // doesn't fit in 24 bits
103*e45e091bSCongcong Cai     // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: narrowing conversion from 'int' to 'float' [bugprone-narrowing-conversions]
104*e45e091bSCongcong Cai     double d = i; // fits in 53 bits.
105*e45e091bSCongcong Cai   }
106*e45e091bSCongcong Cai   {
107*e45e091bSCongcong Cai     short n1, n2;
108*e45e091bSCongcong Cai     float f = n1 + n2; // 'n1 + n2' is of type 'int' because of integer rules
109*e45e091bSCongcong Cai     // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: narrowing conversion from 'int' to 'float' [bugprone-narrowing-conversions]
110*e45e091bSCongcong Cai   }
111*e45e091bSCongcong Cai   {
112*e45e091bSCongcong Cai     short s;      // 16 bits
113*e45e091bSCongcong Cai     float f = s;  // fits in 24 bits
114*e45e091bSCongcong Cai     double d = s; // fits in 53 bits.
115*e45e091bSCongcong Cai   }
116*e45e091bSCongcong Cai }
117*e45e091bSCongcong Cai 
118*e45e091bSCongcong Cai void narrow_integer_to_unsigned_integer_is_ok() {
119*e45e091bSCongcong Cai   char c;
120*e45e091bSCongcong Cai   short s;
121*e45e091bSCongcong Cai   int i;
122*e45e091bSCongcong Cai   long l;
123*e45e091bSCongcong Cai   long long ll;
124*e45e091bSCongcong Cai 
125*e45e091bSCongcong Cai   unsigned char uc;
126*e45e091bSCongcong Cai   unsigned short us;
127*e45e091bSCongcong Cai   unsigned int ui;
128*e45e091bSCongcong Cai   unsigned long ul;
129*e45e091bSCongcong Cai   unsigned long long ull;
130*e45e091bSCongcong Cai 
131*e45e091bSCongcong Cai   ui = c;
132*e45e091bSCongcong Cai   uc = s;
133*e45e091bSCongcong Cai   uc = i;
134*e45e091bSCongcong Cai   uc = l;
135*e45e091bSCongcong Cai   uc = ll;
136*e45e091bSCongcong Cai 
137*e45e091bSCongcong Cai   uc = uc;
138*e45e091bSCongcong Cai   uc = us;
139*e45e091bSCongcong Cai   uc = ui;
140*e45e091bSCongcong Cai   uc = ul;
141*e45e091bSCongcong Cai   uc = ull;
142*e45e091bSCongcong Cai }
143*e45e091bSCongcong Cai 
144*e45e091bSCongcong Cai void narrow_integer_to_signed_integer_is_not_ok() {
145*e45e091bSCongcong Cai   char c;
146*e45e091bSCongcong Cai   short s;
147*e45e091bSCongcong Cai   int i;
148*e45e091bSCongcong Cai   long l;
149*e45e091bSCongcong Cai   long long ll;
150*e45e091bSCongcong Cai 
151*e45e091bSCongcong Cai   unsigned char uc;
152*e45e091bSCongcong Cai   unsigned short us;
153*e45e091bSCongcong Cai   unsigned int ui;
154*e45e091bSCongcong Cai   unsigned long ul;
155*e45e091bSCongcong Cai   unsigned long long ull;
156*e45e091bSCongcong Cai 
157*e45e091bSCongcong Cai   c = c;
158*e45e091bSCongcong Cai   c = s;
159*e45e091bSCongcong Cai   // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'short' to signed type 'char' is implementation-defined [bugprone-narrowing-conversions]
160*e45e091bSCongcong Cai   c = i;
161*e45e091bSCongcong Cai   // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'int' to signed type 'char' is implementation-defined [bugprone-narrowing-conversions]
162*e45e091bSCongcong Cai   c = l;
163*e45e091bSCongcong Cai   // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'long' to signed type 'char' is implementation-defined [bugprone-narrowing-conversions]
164*e45e091bSCongcong Cai   c = ll;
165*e45e091bSCongcong Cai   // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'long long' to signed type 'char' is implementation-defined [bugprone-narrowing-conversions]
166*e45e091bSCongcong Cai 
167*e45e091bSCongcong Cai   c = uc;
168*e45e091bSCongcong Cai   // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'unsigned char' to signed type 'char' is implementation-defined [bugprone-narrowing-conversions]
169*e45e091bSCongcong Cai   c = us;
170*e45e091bSCongcong Cai   // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'unsigned short' to signed type 'char' is implementation-defined [bugprone-narrowing-conversions]
171*e45e091bSCongcong Cai   c = ui;
172*e45e091bSCongcong Cai   // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'unsigned int' to signed type 'char' is implementation-defined [bugprone-narrowing-conversions]
173*e45e091bSCongcong Cai   c = ul;
174*e45e091bSCongcong Cai   // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'unsigned long' to signed type 'char' is implementation-defined [bugprone-narrowing-conversions]
175*e45e091bSCongcong Cai   c = ull;
176*e45e091bSCongcong Cai   // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'unsigned long long' to signed type 'char' is implementation-defined [bugprone-narrowing-conversions]
177*e45e091bSCongcong Cai 
178*e45e091bSCongcong Cai   i = c;
179*e45e091bSCongcong Cai   i = s;
180*e45e091bSCongcong Cai   i = i;
181*e45e091bSCongcong Cai   i = l;
182*e45e091bSCongcong Cai   // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'long' to signed type 'int' is implementation-defined [bugprone-narrowing-conversions]
183*e45e091bSCongcong Cai   i = ll;
184*e45e091bSCongcong Cai   // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'long long' to signed type 'int' is implementation-defined [bugprone-narrowing-conversions]
185*e45e091bSCongcong Cai 
186*e45e091bSCongcong Cai   i = uc;
187*e45e091bSCongcong Cai   i = us;
188*e45e091bSCongcong Cai   i = ui;
189*e45e091bSCongcong Cai   // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'unsigned int' to signed type 'int' is implementation-defined [bugprone-narrowing-conversions]
190*e45e091bSCongcong Cai   i = ul;
191*e45e091bSCongcong Cai   // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'unsigned long' to signed type 'int' is implementation-defined [bugprone-narrowing-conversions]
192*e45e091bSCongcong Cai   i = ull;
193*e45e091bSCongcong Cai   // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'unsigned long long' to signed type 'int' is implementation-defined [bugprone-narrowing-conversions]
194*e45e091bSCongcong Cai 
195*e45e091bSCongcong Cai   ll = c;
196*e45e091bSCongcong Cai   ll = s;
197*e45e091bSCongcong Cai   ll = i;
198*e45e091bSCongcong Cai   ll = l;
199*e45e091bSCongcong Cai   ll = ll;
200*e45e091bSCongcong Cai 
201*e45e091bSCongcong Cai   ll = uc;
202*e45e091bSCongcong Cai   ll = us;
203*e45e091bSCongcong Cai   ll = ui;
204*e45e091bSCongcong Cai   ll = ul;
205*e45e091bSCongcong Cai   // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: narrowing conversion from 'unsigned long' to signed type 'long long' is implementation-defined [bugprone-narrowing-conversions]
206*e45e091bSCongcong Cai   ll = ull;
207*e45e091bSCongcong Cai   // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: narrowing conversion from 'unsigned long long' to signed type 'long long' is implementation-defined [bugprone-narrowing-conversions]
208*e45e091bSCongcong Cai }
209*e45e091bSCongcong Cai 
210*e45e091bSCongcong Cai void narrow_constant_to_unsigned_integer_is_ok() {
211*e45e091bSCongcong Cai   unsigned char uc1 = 0;
212*e45e091bSCongcong Cai   unsigned char uc2 = 255;
213*e45e091bSCongcong Cai   unsigned char uc3 = -1;  // unsigned dst type is well defined.
214*e45e091bSCongcong Cai   unsigned char uc4 = 256; // unsigned dst type is well defined.
215*e45e091bSCongcong Cai   unsigned short us1 = 0;
216*e45e091bSCongcong Cai   unsigned short us2 = 65535;
217*e45e091bSCongcong Cai   unsigned short us3 = -1;    // unsigned dst type is well defined.
218*e45e091bSCongcong Cai   unsigned short us4 = 65536; // unsigned dst type is well defined.
219*e45e091bSCongcong Cai }
220*e45e091bSCongcong Cai 
221*e45e091bSCongcong Cai void narrow_constant_to_signed_integer_is_not_ok() {
222*e45e091bSCongcong Cai   char c1 = -128;
223*e45e091bSCongcong Cai   char c2 = 127;
224*e45e091bSCongcong Cai   char c3 = -129;
225*e45e091bSCongcong Cai   // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: narrowing conversion from constant value -129 (0xFFFFFF7F) of type 'int' to signed type 'char' is implementation-defined [bugprone-narrowing-conversions]
226*e45e091bSCongcong Cai   char c4 = 128;
227*e45e091bSCongcong Cai   // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: narrowing conversion from constant value 128 (0x00000080) of type 'int' to signed type 'char' is implementation-defined [bugprone-narrowing-conversions]
228*e45e091bSCongcong Cai 
229*e45e091bSCongcong Cai   short s1 = -32768;
230*e45e091bSCongcong Cai   short s2 = 32767;
231*e45e091bSCongcong Cai   short s3 = -32769;
232*e45e091bSCongcong Cai   // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: narrowing conversion from constant value -32769 (0xFFFF7FFF) of type 'int' to signed type 'short' is implementation-defined [bugprone-narrowing-conversions]
233*e45e091bSCongcong Cai   short s4 = 32768;
234*e45e091bSCongcong Cai   // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: narrowing conversion from constant value 32768 (0x00008000) of type 'int' to signed type 'short' is implementation-defined [bugprone-narrowing-conversions]
235*e45e091bSCongcong Cai }
236*e45e091bSCongcong Cai 
237*e45e091bSCongcong Cai void narrow_conditional_operator_contant_to_unsigned_is_ok(bool b) {
238*e45e091bSCongcong Cai   // conversion to unsigned dst type is well defined.
239*e45e091bSCongcong Cai   unsigned char c1 = b ? 1 : 0;
240*e45e091bSCongcong Cai   unsigned char c2 = b ? 1 : 256;
241*e45e091bSCongcong Cai   unsigned char c3 = b ? -1 : 0;
242*e45e091bSCongcong Cai }
243*e45e091bSCongcong Cai 
244*e45e091bSCongcong Cai void narrow_conditional_operator_contant_to_signed_is_not_ok(bool b) {
245*e45e091bSCongcong Cai   char uc1 = b ? 1 : 0;
246*e45e091bSCongcong Cai   char uc2 = b ? 1 : 128;
247*e45e091bSCongcong Cai   // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: narrowing conversion from constant value 128 (0x00000080) of type 'int' to signed type 'char' is implementation-defined [bugprone-narrowing-conversions]
248*e45e091bSCongcong Cai   char uc3 = b ? -129 : 0;
249*e45e091bSCongcong Cai   // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: narrowing conversion from constant value -129 (0xFFFFFF7F) of type 'int' to signed type 'char' is implementation-defined [bugprone-narrowing-conversions]
250*e45e091bSCongcong Cai   unsigned long long ysize;
251*e45e091bSCongcong Cai   long long mirror = b ? -1 : ysize - 1;
252*e45e091bSCongcong Cai   // CHECK-MESSAGES: :[[@LINE-1]]:26: warning: narrowing conversion from constant value 18446744073709551615 (0xFFFFFFFFFFFFFFFF) of type 'unsigned long long' to signed type 'long long' is implementation-defined [bugprone-narrowing-conversions]
253*e45e091bSCongcong Cai   // CHECK-MESSAGES: :[[@LINE-2]]:37: warning: narrowing conversion from 'unsigned long long' to signed type 'long long' is implementation-defined [bugprone-narrowing-conversions]
254*e45e091bSCongcong Cai }
255*e45e091bSCongcong Cai 
256*e45e091bSCongcong Cai void narrow_constant_to_floating_point() {
257*e45e091bSCongcong Cai   float f_ok = 1ULL << 24;              // fits in 24 bits mantissa.
258*e45e091bSCongcong Cai   float f_not_ok = (1ULL << 24) + 1ULL; // doesn't fit in 24 bits mantissa.
259*e45e091bSCongcong Cai   // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: narrowing conversion from constant value 16777217 of type 'unsigned long long' to 'float' [bugprone-narrowing-conversions]
260*e45e091bSCongcong Cai   double d_ok = 1ULL << 53;              // fits in 53 bits mantissa.
261*e45e091bSCongcong Cai   double d_not_ok = (1ULL << 53) + 1ULL; // doesn't fit in 53 bits mantissa.
262*e45e091bSCongcong Cai   // CHECK-MESSAGES: :[[@LINE-1]]:21: warning: narrowing conversion from constant value 9007199254740993 of type 'unsigned long long' to 'double' [bugprone-narrowing-conversions]
263*e45e091bSCongcong Cai }
264*e45e091bSCongcong Cai 
265*e45e091bSCongcong Cai void casting_integer_to_bool_is_ok() {
266*e45e091bSCongcong Cai   int i;
267*e45e091bSCongcong Cai   while (i) {
268*e45e091bSCongcong Cai   }
269*e45e091bSCongcong Cai   for (; i;) {
270*e45e091bSCongcong Cai   }
271*e45e091bSCongcong Cai   if (i) {
272*e45e091bSCongcong Cai   }
273*e45e091bSCongcong Cai }
274*e45e091bSCongcong Cai 
275*e45e091bSCongcong Cai void casting_float_to_bool_is_not_ok() {
276*e45e091bSCongcong Cai   float f;
277*e45e091bSCongcong Cai   while (f) {
278*e45e091bSCongcong Cai     // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: narrowing conversion from 'float' to 'bool' [bugprone-narrowing-conversions]
279*e45e091bSCongcong Cai   }
280*e45e091bSCongcong Cai   for (; f;) {
281*e45e091bSCongcong Cai     // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: narrowing conversion from 'float' to 'bool' [bugprone-narrowing-conversions]
282*e45e091bSCongcong Cai   }
283*e45e091bSCongcong Cai   if (f) {
284*e45e091bSCongcong Cai     // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'float' to 'bool' [bugprone-narrowing-conversions]
285*e45e091bSCongcong Cai   }
286*e45e091bSCongcong Cai }
287*e45e091bSCongcong Cai 
288*e45e091bSCongcong Cai void legitimate_comparison_do_not_warn(unsigned long long size) {
289*e45e091bSCongcong Cai   for (int i = 0; i < size; ++i) {
290*e45e091bSCongcong Cai   }
291*e45e091bSCongcong Cai }
292*e45e091bSCongcong Cai 
293*e45e091bSCongcong Cai void ok(double d) {
294*e45e091bSCongcong Cai   int i = 0;
295*e45e091bSCongcong Cai   i = 1;
296*e45e091bSCongcong Cai   i = static_cast<int>(0.5);
297*e45e091bSCongcong Cai   i = static_cast<int>(d);
298*e45e091bSCongcong Cai   i = std::ceil(0.5);
299*e45e091bSCongcong Cai   i = ::std::floor(0.5);
300*e45e091bSCongcong Cai   {
301*e45e091bSCongcong Cai     using std::ceil;
302*e45e091bSCongcong Cai     i = ceil(0.5f);
303*e45e091bSCongcong Cai   }
304*e45e091bSCongcong Cai   i = ceil(0.5f);
305*e45e091bSCongcong Cai }
306*e45e091bSCongcong Cai 
307*e45e091bSCongcong Cai void ok_binary_ops(double d) {
308*e45e091bSCongcong Cai   int i = 0;
309*e45e091bSCongcong Cai   i += 1;
310*e45e091bSCongcong Cai   i += static_cast<int>(0.5);
311*e45e091bSCongcong Cai   i += static_cast<int>(d);
312*e45e091bSCongcong Cai   i += (int)d;
313*e45e091bSCongcong Cai   i += std::ceil(0.5);
314*e45e091bSCongcong Cai   i += ::std::floor(0.5);
315*e45e091bSCongcong Cai   {
316*e45e091bSCongcong Cai     using std::ceil;
317*e45e091bSCongcong Cai     i += ceil(0.5f);
318*e45e091bSCongcong Cai   }
319*e45e091bSCongcong Cai   i += ceil(0.5f);
320*e45e091bSCongcong Cai }
321*e45e091bSCongcong Cai 
322*e45e091bSCongcong Cai // We're bailing out in templates and macros.
323*e45e091bSCongcong Cai template <typename T1, typename T2>
324*e45e091bSCongcong Cai void f(T1 one, T2 two) {
325*e45e091bSCongcong Cai   one += two;
326*e45e091bSCongcong Cai }
327*e45e091bSCongcong Cai 
328*e45e091bSCongcong Cai void template_context() {
329*e45e091bSCongcong Cai   f(1, 2);
330*e45e091bSCongcong Cai   f(1, .5f);
331*e45e091bSCongcong Cai   f(1, .5);
332*e45e091bSCongcong Cai   f(1, .5l);
333*e45e091bSCongcong Cai }
334*e45e091bSCongcong Cai 
335*e45e091bSCongcong Cai #define DERP(i, j) (i += j)
336*e45e091bSCongcong Cai 
337*e45e091bSCongcong Cai void macro_context() {
338*e45e091bSCongcong Cai   int i = 0;
339*e45e091bSCongcong Cai   DERP(i, 2);
340*e45e091bSCongcong Cai   DERP(i, .5f);
341*e45e091bSCongcong Cai   DERP(i, .5);
342*e45e091bSCongcong Cai   DERP(i, .5l);
343*e45e091bSCongcong Cai }
344*e45e091bSCongcong Cai 
345*e45e091bSCongcong Cai // We understand typedefs.
346*e45e091bSCongcong Cai void typedef_context() {
347*e45e091bSCongcong Cai   typedef long long myint64_t;
348*e45e091bSCongcong Cai   int i;
349*e45e091bSCongcong Cai   myint64_t i64;
350*e45e091bSCongcong Cai 
351*e45e091bSCongcong Cai   i64 = i64; // Okay, no conversion.
352*e45e091bSCongcong Cai   i64 = i;   // Okay, no narrowing.
353*e45e091bSCongcong Cai 
354*e45e091bSCongcong Cai   i = i64;
355*e45e091bSCongcong Cai   // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'myint64_t' (aka 'long long') to signed type 'int' is implementation-defined [bugprone-narrowing-conversions]
356*e45e091bSCongcong Cai }
357*e45e091bSCongcong Cai 
358*e45e091bSCongcong Cai } // namespace floats
359