| // RUN: %clang_cc1 -fsyntax-only -verify -Wconversion \ |
| // RUN: -nostdsysteminc -nobuiltininc -isystem %S/Inputs \ |
| // RUN: -triple x86_64-apple-darwin %s -Wno-unreachable-code |
| |
| #include <conversion.h> |
| |
| #define BIG 0x7f7f7f7f7f7f7f7fL |
| |
| void test0(char c, short s, int i, long l, long long ll) { |
| c = c; |
| c = s; // expected-warning {{implicit conversion loses integer precision}} |
| c = i; // expected-warning {{implicit conversion loses integer precision}} |
| c = l; // expected-warning {{implicit conversion loses integer precision}} |
| s = c; |
| s = s; |
| s = i; // expected-warning {{implicit conversion loses integer precision}} |
| s = l; // expected-warning {{implicit conversion loses integer precision}} |
| i = c; |
| i = s; |
| i = i; |
| i = l; // expected-warning {{implicit conversion loses integer precision}} |
| l = c; |
| l = s; |
| l = i; |
| l = l; |
| |
| c = (char) 0; |
| c = (short) 0; |
| c = (int) 0; |
| c = (long) 0; |
| s = (char) 0; |
| s = (short) 0; |
| s = (int) 0; |
| s = (long) 0; |
| i = (char) 0; |
| i = (short) 0; |
| i = (int) 0; |
| i = (long) 0; |
| l = (char) 0; |
| l = (short) 0; |
| l = (int) 0; |
| l = (long) 0; |
| |
| c = (char) BIG; |
| c = (short) BIG; // expected-warning {{implicit conversion from 'short' to 'char' changes value}} |
| c = (int) BIG; // expected-warning {{implicit conversion from 'int' to 'char' changes value}} |
| c = (long) BIG; // expected-warning {{implicit conversion from 'long' to 'char' changes value}} |
| s = (char) BIG; |
| s = (short) BIG; |
| s = (int) BIG; // expected-warning {{implicit conversion from 'int' to 'short' changes value}} |
| s = (long) BIG; // expected-warning {{implicit conversion from 'long' to 'short' changes value}} |
| i = (char) BIG; |
| i = (short) BIG; |
| i = (int) BIG; |
| i = (long) BIG; // expected-warning {{implicit conversion from 'long' to 'int' changes value}} |
| l = (char) BIG; |
| l = (short) BIG; |
| l = (int) BIG; |
| l = (long) BIG; |
| } |
| |
| char test1(long long ll) { |
| return (long long) ll; // expected-warning {{implicit conversion loses integer precision}} |
| } |
| char test1_a(long long ll) { |
| return (long) ll; // expected-warning {{implicit conversion loses integer precision}} |
| } |
| char test1_b(long long ll) { |
| return (int) ll; // expected-warning {{implicit conversion loses integer precision}} |
| } |
| char test1_c(long long ll) { |
| return (short) ll; // expected-warning {{implicit conversion loses integer precision}} |
| } |
| char test1_d(long long ll) { |
| return (char) ll; |
| } |
| char test1_e(long long ll) { |
| return (long long) BIG; // expected-warning {{implicit conversion from 'long long' to 'char' changes value}} |
| } |
| char test1_f(long long ll) { |
| return (long) BIG; // expected-warning {{implicit conversion from 'long' to 'char' changes value}} |
| } |
| char test1_g(long long ll) { |
| return (int) BIG; // expected-warning {{implicit conversion from 'int' to 'char' changes value}} |
| } |
| char test1_h(long long ll) { |
| return (short) BIG; // expected-warning {{implicit conversion from 'short' to 'char' changes value}} |
| } |
| char test1_i(long long ll) { |
| return (char) BIG; |
| } |
| |
| short test2(long long ll) { |
| return (long long) ll; // expected-warning {{implicit conversion loses integer precision}} |
| } |
| short test2_a(long long ll) { |
| return (long) ll; // expected-warning {{implicit conversion loses integer precision}} |
| } |
| short test2_b(long long ll) { |
| return (int) ll; // expected-warning {{implicit conversion loses integer precision}} |
| } |
| short test2_c(long long ll) { |
| return (short) ll; |
| } |
| short test2_d(long long ll) { |
| return (char) ll; |
| } |
| short test2_e(long long ll) { |
| return (long long) BIG; // expected-warning {{implicit conversion from 'long long' to 'short' changes value}} |
| } |
| short test2_f(long long ll) { |
| return (long) BIG; // expected-warning {{implicit conversion from 'long' to 'short' changes value}} |
| } |
| short test2_g(long long ll) { |
| return (int) BIG; // expected-warning {{implicit conversion from 'int' to 'short' changes value}} |
| } |
| short test2_h(long long ll) { |
| return (short) BIG; |
| } |
| short test2_i(long long ll) { |
| return (char) BIG; |
| } |
| |
| int test3(long long ll) { |
| return (long long) ll; // expected-warning {{implicit conversion loses integer precision}} |
| } |
| int test3_b(long long ll) { |
| return (long) ll; // expected-warning {{implicit conversion loses integer precision}} |
| } |
| int test3_c(long long ll) { |
| return (int) ll; |
| } |
| int test3_d(long long ll) { |
| return (short) ll; |
| } |
| int test3_e(long long ll) { |
| return (char) ll; |
| } |
| int test3_f(long long ll) { |
| return (long long) BIG; // expected-warning {{implicit conversion from 'long long' to 'int' changes value}} |
| } |
| int test3_g(long long ll) { |
| return (long) BIG; // expected-warning {{implicit conversion from 'long' to 'int' changes value}} |
| } |
| int test3_h(long long ll) { |
| return (int) BIG; |
| } |
| int test3_i(long long ll) { |
| return (short) BIG; |
| } |
| int test3_j(long long ll) { |
| return (char) BIG; |
| } |
| |
| long test4(long long ll) { |
| return (long long) ll; |
| } |
| long test4_a(long long ll) { |
| return (long) ll; |
| } |
| long test4_b(long long ll) { |
| return (int) ll; |
| } |
| long test4_c(long long ll) { |
| return (short) ll; |
| } |
| long test4_d(long long ll) { |
| return (char) ll; |
| } |
| long test4_e(long long ll) { |
| return (long long) BIG; |
| } |
| long test4_f(long long ll) { |
| return (long) BIG; |
| } |
| long test4_g(long long ll) { |
| return (int) BIG; |
| } |
| long test4_h(long long ll) { |
| return (short) BIG; |
| } |
| long test4_i(long long ll) { |
| return (char) BIG; |
| } |
| |
| long long test5(long long ll) { |
| return (long long) ll; |
| return (long) ll; |
| return (int) ll; |
| return (short) ll; |
| return (char) ll; |
| return (long long) BIG; |
| return (long) BIG; |
| return (int) BIG; |
| return (short) BIG; |
| return (char) BIG; |
| } |
| |
| void takes_char(char); |
| void takes_short(short); |
| void takes_int(int); |
| void takes_long(long); |
| void takes_longlong(long long); |
| void takes_float(float); |
| void takes_double(double); |
| void takes_longdouble(long double); |
| |
| void test6(char v) { |
| takes_char(v); |
| takes_short(v); |
| takes_int(v); |
| takes_long(v); |
| takes_longlong(v); |
| takes_float(v); |
| takes_double(v); |
| takes_longdouble(v); |
| } |
| |
| void test7(short v) { |
| takes_char(v); // expected-warning {{implicit conversion loses integer precision}} |
| takes_short(v); |
| takes_int(v); |
| takes_long(v); |
| takes_longlong(v); |
| takes_float(v); |
| takes_double(v); |
| takes_longdouble(v); |
| } |
| |
| void test8(int v) { |
| takes_char(v); // expected-warning {{implicit conversion loses integer precision}} |
| takes_short(v); // expected-warning {{implicit conversion loses integer precision}} |
| takes_int(v); |
| takes_long(v); |
| takes_longlong(v); |
| takes_float(v); |
| takes_double(v); |
| takes_longdouble(v); |
| } |
| |
| void test9(long v) { |
| takes_char(v); // expected-warning {{implicit conversion loses integer precision}} |
| takes_short(v); // expected-warning {{implicit conversion loses integer precision}} |
| takes_int(v); // expected-warning {{implicit conversion loses integer precision}} |
| takes_long(v); |
| takes_longlong(v); |
| takes_float(v); |
| takes_double(v); |
| takes_longdouble(v); |
| } |
| |
| void test10(long long v) { |
| takes_char(v); // expected-warning {{implicit conversion loses integer precision}} |
| takes_short(v); // expected-warning {{implicit conversion loses integer precision}} |
| takes_int(v); // expected-warning {{implicit conversion loses integer precision}} |
| takes_long(v); |
| takes_longlong(v); |
| takes_float(v); |
| takes_double(v); |
| takes_longdouble(v); |
| } |
| |
| void test11(float v) { |
| takes_char(v); // expected-warning {{implicit conversion turns floating-point number into integer}} |
| takes_short(v); // expected-warning {{implicit conversion turns floating-point number into integer}} |
| takes_int(v); // expected-warning {{implicit conversion turns floating-point number into integer}} |
| takes_long(v); // expected-warning {{implicit conversion turns floating-point number into integer}} |
| takes_longlong(v); // expected-warning {{implicit conversion turns floating-point number into integer}} |
| takes_float(v); |
| takes_double(v); |
| takes_longdouble(v); |
| } |
| |
| void test12(double v) { |
| takes_char(v); // expected-warning {{implicit conversion turns floating-point number into integer}} |
| takes_short(v); // expected-warning {{implicit conversion turns floating-point number into integer}} |
| takes_int(v); // expected-warning {{implicit conversion turns floating-point number into integer}} |
| takes_long(v); // expected-warning {{implicit conversion turns floating-point number into integer}} |
| takes_longlong(v); // expected-warning {{implicit conversion turns floating-point number into integer}} |
| takes_float(v); // expected-warning {{implicit conversion loses floating-point precision}} |
| takes_double(v); |
| takes_longdouble(v); |
| } |
| |
| void test13(long double v) { |
| takes_char(v); // expected-warning {{implicit conversion turns floating-point number into integer}} |
| takes_short(v); // expected-warning {{implicit conversion turns floating-point number into integer}} |
| takes_int(v); // expected-warning {{implicit conversion turns floating-point number into integer}} |
| takes_long(v); // expected-warning {{implicit conversion turns floating-point number into integer}} |
| takes_longlong(v); // expected-warning {{implicit conversion turns floating-point number into integer}} |
| takes_float(v); // expected-warning {{implicit conversion loses floating-point precision}} |
| takes_double(v); // expected-warning {{implicit conversion loses floating-point precision}} |
| takes_longdouble(v); |
| } |
| |
| void test14(long l) { |
| // Fine because of the boolean whitelist. |
| char c; |
| c = (l == 4); |
| c = ((l <= 4) && (l >= 0)); |
| c = ((l <= 4) && (l >= 0)) || (l > 20); |
| } |
| |
| void test15(char c) { |
| c = c + 1 + c * 2; |
| c = (short) c + 1 + c * 2; // expected-warning {{implicit conversion loses integer precision}} |
| } |
| |
| // PR 5422 |
| extern void *test16_external; |
| void test16(void) { |
| int a = (unsigned long) &test16_external; // expected-warning {{implicit conversion loses integer precision}} |
| } |
| |
| // PR 5938 |
| void test17() { |
| union { |
| unsigned long long a : 8; |
| unsigned long long b : 32; |
| unsigned long long c; |
| } U; |
| |
| unsigned int x; |
| x = U.a; |
| x = U.b; |
| x = U.c; // expected-warning {{implicit conversion loses integer precision}} |
| } |
| |
| // PR 5939 |
| void test18() { |
| union { |
| unsigned long long a : 1; |
| unsigned long long b; |
| } U; |
| |
| int x; |
| x = (U.a ? 0 : 1); |
| x = (U.b ? 0 : 1); |
| } |
| |
| // None of these should warn. |
| unsigned char test19(unsigned long u64) { |
| unsigned char x1 = u64 & 0xff; |
| unsigned char x2 = u64 >> 56; |
| |
| unsigned char mask = 0xee; |
| unsigned char x3 = u64 & mask; |
| return x1 + x2 + x3; |
| } |
| |
| // <rdar://problem/7631400> |
| void test_7631400(void) { |
| // This should show up despite the caret being inside a macro substitution |
| char s = LONG_MAX; // expected-warning {{implicit conversion from 'long' to 'char' changes value}} |
| } |
| |
| // <rdar://problem/7676608>: assertion for compound operators with non-integral RHS |
| void f7676608(int); |
| void test_7676608(void) { |
| float q = 0.7f; |
| char c = 5; |
| f7676608(c *= q); |
| } |
| |
| // <rdar://problem/7904686> |
| void test_7904686(void) { |
| const int i = -1; |
| unsigned u1 = i; // expected-warning {{implicit conversion changes signedness}} |
| u1 = i; // expected-warning {{implicit conversion changes signedness}} |
| |
| unsigned u2 = -1; // expected-warning {{implicit conversion changes signedness}} |
| u2 = -1; // expected-warning {{implicit conversion changes signedness}} |
| } |
| |
| // <rdar://problem/8232669>: don't warn about conversions required by |
| // contexts in system headers |
| void test_8232669(void) { |
| unsigned bitset[20]; |
| SETBIT(bitset, 0); |
| |
| unsigned y = 50; |
| SETBIT(bitset, y); |
| |
| #define USER_SETBIT(set,bit) do { int i = bit; set[i/(8*sizeof(set[0]))] |= (1 << (i%(8*sizeof(set)))); } while(0) |
| USER_SETBIT(bitset, 0); // expected-warning 2 {{implicit conversion changes signedness}} |
| } |
| |
| // <rdar://problem/8559831> |
| enum E8559831a { E8559831a_val }; |
| enum E8559831b { E8559831b_val }; |
| typedef enum { E8559831c_val } E8559831c; |
| enum { E8559831d_val } value_d; |
| |
| void test_8559831_a(enum E8559831a value); |
| void test_8559831(enum E8559831b value_a, E8559831c value_c) { |
| test_8559831_a(value_a); // expected-warning{{implicit conversion from enumeration type 'enum E8559831b' to different enumeration type 'enum E8559831a'}} |
| enum E8559831a a1 = value_a; // expected-warning{{implicit conversion from enumeration type 'enum E8559831b' to different enumeration type 'enum E8559831a'}} |
| a1 = value_a; // expected-warning{{implicit conversion from enumeration type 'enum E8559831b' to different enumeration type 'enum E8559831a'}} |
| |
| test_8559831_a(E8559831b_val); // expected-warning{{implicit conversion from enumeration type 'enum E8559831b' to different enumeration type 'enum E8559831a'}} |
| enum E8559831a a1a = E8559831b_val; // expected-warning{{implicit conversion from enumeration type 'enum E8559831b' to different enumeration type 'enum E8559831a'}} |
| a1 = E8559831b_val; // expected-warning{{implicit conversion from enumeration type 'enum E8559831b' to different enumeration type 'enum E8559831a'}} |
| |
| test_8559831_a(value_c); // expected-warning{{implicit conversion from enumeration type 'E8559831c' to different enumeration type 'enum E8559831a'}} |
| enum E8559831a a2 = value_c; // expected-warning{{implicit conversion from enumeration type 'E8559831c' to different enumeration type 'enum E8559831a'}} |
| a2 = value_c; // expected-warning{{implicit conversion from enumeration type 'E8559831c' to different enumeration type 'enum E8559831a'}} |
| |
| test_8559831_a(value_d); |
| enum E8559831a a3 = value_d; |
| a3 = value_d; |
| } |
| |
| void test26(int si, long sl) { |
| si = sl % sl; // expected-warning {{implicit conversion loses integer precision: 'long' to 'int'}} |
| si = sl % si; |
| si = si % sl; |
| si = si / sl; |
| si = sl / si; // expected-warning {{implicit conversion loses integer precision: 'long' to 'int'}} |
| } |