| 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 | |