1 | // RUN: %clang_cc1 -fsyntax-only -Wliteral-conversion -verify %s |
2 | |
3 | void foo(int y); |
4 | |
5 | // Warn when a literal float or double is assigned or bound to an integer. |
6 | void test0() { |
7 | // Float |
8 | int y0 = 1.2222F; // expected-warning {{implicit conversion from 'float' to 'int' changes value from 1.2222 to 1}} |
9 | int y1 = (1.2222F); // expected-warning {{implicit conversion from 'float' to 'int' changes value from 1.2222 to 1}} |
10 | int y2 = (((1.2222F))); // expected-warning {{implicit conversion from 'float' to 'int' changes value from 1.2222 to 1}} |
11 | int y3 = 12E-1F; // expected-warning {{implicit conversion from 'float' to 'int' changes value from 1.2 to 1}} |
12 | int y4 = 1.23E1F; // expected-warning {{implicit conversion from 'float' to 'int' changes value from 12.3 to 12}} |
13 | // Double |
14 | int y5 = 1.2222; // expected-warning {{implicit conversion from 'double' to 'int' changes value from 1.2222 to 1}} |
15 | int y6 = 12E-1; // expected-warning {{implicit conversion from 'double' to 'int' changes value from 1.2 to 1}} |
16 | int y7 = 1.23E1; // expected-warning {{implicit conversion from 'double' to 'int' changes value from 12.3 to 12}} |
17 | int y8 = (1.23E1); // expected-warning {{implicit conversion from 'double' to 'int' changes value from 12.3 to 12}} |
18 | |
19 | // Test assignment to an existing variable. |
20 | y8 = 2.22F; // expected-warning {{implicit conversion from 'float' to 'int' changes value from 2.22 to 2}} |
21 | |
22 | // Test direct initialization. |
23 | int y9(1.23F); // expected-warning {{implicit conversion from 'float' to 'int' changes value from 1.23 to 1}} |
24 | |
25 | // Test passing a literal floating-point value to a function that takes an integer. |
26 | foo(1.2F); // expected-warning {{implicit conversion from 'float' to 'int' changes value from 1.2 to 1}} |
27 | |
28 | int y10 = -1.2F; // expected-warning {{implicit conversion from 'float' to 'int' changes value from -1.2 to -1}} |
29 | |
30 | // -Wliteral-conversion does NOT catch const values. |
31 | // (-Wconversion DOES catch them.) |
32 | static const float sales_tax_rate = .095F; |
33 | int z = sales_tax_rate; |
34 | foo(sales_tax_rate); |
35 | |
36 | // Expressions, such as those that indicate rounding-down, should NOT produce warnings. |
37 | int x = 24 * 0.5; |
38 | int y = (24*60*60) * 0.25; |
39 | int pennies = 123.45 * 100; |
40 | } |
41 | |
42 | // Similarly, test floating point conversion to bool. Only float values of zero |
43 | // are converted to false; everything else is converted to true. |
44 | void test1() { |
45 | bool b1 = 0.99f; // expected-warning {{implicit conversion from 'float' to 'bool' changes value from 0.99 to true}} |
46 | bool b2 = 0.99; // expected-warning {{implicit conversion from 'double' to 'bool' changes value from 0.99 to true}} |
47 | // These do not warn because they can be directly converted to integral |
48 | // values. |
49 | bool b3 = 0.0f; |
50 | bool b4 = 0.0; |
51 | |
52 | // These all warn because they overflow the target type. |
53 | short s = 32768.0; // expected-warning{{implicit conversion of out of range value from 'double' to 'short' is undefined}} |
54 | unsigned short us = 65536.0; // expected-warning{{implicit conversion of out of range value from 'double' to 'unsigned short' is undefined}} |
55 | |
56 | short s2 = -32769.0; // expected-warning{{implicit conversion of out of range value from 'double' to 'short' is undefined}} |
57 | unsigned short us2 = -65537.0; // expected-warning{{implicit conversion of out of range value from 'double' to 'unsigned short' is undefined}} |
58 | } |
59 | |
60 | int a() { return 2147483647.5; } // expected-warning{{implicit conversion from 'double' to 'int' changes value from 2147483647.5 to 2147483647}} |
61 | unsigned b() { return -.5; } // expected-warning{{implicit conversion from 'double' to 'unsigned int' changes value from -0.5 to 0}} |
62 | |
63 | |