|  | // RUN: %clang_cc1 -fsyntax-only -verify -Wconversion -nostdinc -isystem %S/Inputs -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}} | 
|  | return (long) ll; // expected-warning {{implicit conversion loses integer precision}} | 
|  | return (int) ll; // expected-warning {{implicit conversion loses integer precision}} | 
|  | return (short) ll; // expected-warning {{implicit conversion loses integer precision}} | 
|  | return (char) ll; | 
|  | return (long long) BIG; // expected-warning {{implicit conversion from 'long long' to 'char' changes value}} | 
|  | return (long) BIG; // expected-warning {{implicit conversion from 'long' to 'char' changes value}} | 
|  | return (int) BIG; // expected-warning {{implicit conversion from 'int' to 'char' changes value}} | 
|  | return (short) BIG; // expected-warning {{implicit conversion from 'short' to 'char' changes value}} | 
|  | return (char) BIG; | 
|  | } | 
|  |  | 
|  | short test2(long long ll) { | 
|  | return (long long) ll; // expected-warning {{implicit conversion loses integer precision}} | 
|  | return (long) ll; // expected-warning {{implicit conversion loses integer precision}} | 
|  | return (int) ll; // expected-warning {{implicit conversion loses integer precision}} | 
|  | return (short) ll; | 
|  | return (char) ll; | 
|  | return (long long) BIG;  // expected-warning {{implicit conversion from 'long long' to 'short' changes value}} | 
|  | return (long) BIG;  // expected-warning {{implicit conversion from 'long' to 'short' changes value}} | 
|  | return (int) BIG;  // expected-warning {{implicit conversion from 'int' to 'short' changes value}} | 
|  | return (short) BIG; | 
|  | return (char) BIG; | 
|  | } | 
|  |  | 
|  | int test3(long long ll) { | 
|  | return (long long) ll;  // expected-warning {{implicit conversion loses integer precision}} | 
|  | return (long) ll;  // expected-warning {{implicit conversion loses integer precision}} | 
|  | return (int) ll; | 
|  | return (short) ll; | 
|  | return (char) ll; | 
|  | return (long long) BIG;  // expected-warning {{implicit conversion from 'long long' to 'int' changes value}} | 
|  | return (long) BIG; // expected-warning {{implicit conversion from 'long' to 'int' changes value}} | 
|  | return (int) BIG; | 
|  | return (short) BIG; | 
|  | return (char) BIG; | 
|  | } | 
|  |  | 
|  | long test4(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; | 
|  | } | 
|  |  | 
|  | 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}} | 
|  | } |