1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152
|
// RUN: %clang_cc1 -verify -fsyntax-only -triple x86_64-pc-linux-gnu %s -Wno-literal-conversion -Wfloat-conversion -DFLOAT_CONVERSION -DZERO -DBOOL -DCONSTANT_BOOL -DOVERFLOW
// RUN: %clang_cc1 -verify -fsyntax-only -triple x86_64-pc-linux-gnu %s -Wno-conversion -Wfloat-overflow-conversion -DOVERFLOW
// RUN: %clang_cc1 -verify -fsyntax-only -triple x86_64-pc-linux-gnu %s -Wno-conversion -Wfloat-zero-conversion -DZERO
float ReturnFloat();
#ifdef FLOAT_CONVERSION
bool ReturnBool(float f) {
return f; //expected-warning{{conversion}}
}
char ReturnChar(float f) {
return f; //expected-warning{{conversion}}
}
int ReturnInt(float f) {
return f; //expected-warning{{conversion}}
}
long ReturnLong(float f) {
return f; //expected-warning{{conversion}}
}
void Convert(float f, double d, long double ld) {
bool b;
char c;
int i;
long l;
b = f; //expected-warning{{conversion}}
b = d; //expected-warning{{conversion}}
b = ld; //expected-warning{{conversion}}
c = f; //expected-warning{{conversion}}
c = d; //expected-warning{{conversion}}
c = ld; //expected-warning{{conversion}}
i = f; //expected-warning{{conversion}}
i = d; //expected-warning{{conversion}}
i = ld; //expected-warning{{conversion}}
l = f; //expected-warning{{conversion}}
l = d; //expected-warning{{conversion}}
l = ld; //expected-warning{{conversion}}
}
void CompoundAssignment() {
int x = 3;
x += 1.234; // expected-warning {{implicit conversion turns floating-point number into integer: 'double' to 'int'}}
x -= -0.0; // expected-warning {{implicit conversion turns floating-point number into integer: 'double' to 'int'}}
x *= 1.1f; // expected-warning {{implicit conversion turns floating-point number into integer: 'float' to 'int'}}
x /= -2.2f; // expected-warning {{implicit conversion turns floating-point number into integer: 'float' to 'int'}}
int y = x += 1.4f; // expected-warning {{implicit conversion turns floating-point number into integer: 'float' to 'int'}}
float z = 1.1f;
double w = -2.2;
y += z + w; // expected-warning {{implicit conversion turns floating-point number into integer: 'double' to 'int'}}
}
# 1 "foo.h" 3
// ^ the following text comes from a system header file.
#define SYSTEM_MACRO_FLOAT(x) do { (x) += 1.1; } while(0)
# 1 "warn-float-conversion.cpp" 1
// ^ start of a new file.
void SystemMacro() {
float x = 0.0f;
SYSTEM_MACRO_FLOAT(x);
}
void Test() {
int a1 = 10.0/2.0; //expected-warning{{conversion}}
int a2 = 1.0/2.0; //expected-warning{{conversion}}
bool a3 = ReturnFloat(); //expected-warning{{conversion}}
int a4 = 1e30 + 1; //expected-warning{{conversion}}
}
void TestConstantFloat() {
// Don't warn on exact floating literals.
int a1 = 5.0;
int a2 = 1e3;
int a3 = 5.5; // caught by -Wliteral-conversion
int a4 = 500.44; // caught by -Wliteral-convserion
int b1 = 5.0 / 1.0; //expected-warning{{conversion}}
int b2 = 5.0 / 2.0; //expected-warning{{conversion}}
const float five = 5.0;
int b3 = five / 1.0; //expected-warning{{conversion}}
int b4 = five / 2.0; //expected-warning{{conversion}}
int f = 2147483646.5 + 1; // expected-warning{{implicit conversion from 'double' to 'int' changes value from 2147483647.5 to 2147483647}}
unsigned g = -.5 + .01; // expected-warning{{implicit conversion from 'double' to 'unsigned int' changes non-zero value from -0.49 to 0}}
}
#endif // FLOAT_CONVERSION
#ifdef ZERO
void TestZero() {
const float half = .5;
int a1 = half; // expected-warning{{implicit conversion from 'const float' to 'int' changes non-zero value from 0.5 to 0}}
int a2 = 1.0 / 2.0; // expected-warning{{implicit conversion from 'double' to 'int' changes non-zero value from 0.5 to 0}}
int a3 = 5;
}
#endif // ZERO
#ifdef OVERFLOW
void TestOverflow() {
char a = 500.0; // caught by -Wliteral-conversion
char b = -500.0; // caught by -Wliteral-conversion
const float LargeNumber = 1024;
char c = LargeNumber; // expected-warning{{implicit conversion of out of range value from 'const float' to 'char' is undefined}}
char d = 400.0 + 400.0; // expected-warning{{implicit conversion of out of range value from 'double' to 'char' is undefined}}
char e = 1.0 / 0.0; // expected-warning{{implicit conversion of out of range value from 'double' to 'char' is undefined}}
}
template <typename T>
class Check {
public:
static constexpr bool Safe();
};
template<>
constexpr bool Check<char>::Safe() { return false; }
template<>
constexpr bool Check<float>::Safe() { return true; }
template <typename T>
T run1(T t) {
const float ret = 800;
return ret; // expected-warning {{implicit conversion of out of range value from 'const float' to 'char' is undefined}}
}
template <typename T>
T run2(T t) {
const float ret = 800;
if (Check<T>::Safe())
return ret;
else
return t;
}
void test() {
float a = run1(a) + run2(a);
char b = run1(b) + run2(b); // expected-note {{in instantiation of function template specialization 'run1<char>' requested here}}
}
#endif // OVERFLOW
|