2010-02-12 06:45:16 +08:00
// RUN: %clang_cc1 -fsyntax-only -verify -Wconversion -nostdinc -isystem %S/Inputs -triple x86_64-apple-darwin %s -Wno-unreachable-code
2009-11-07 11:30:38 +08:00
2010-02-12 06:45:16 +08:00
# include <conversion.h>
2010-02-12 02:52:49 +08:00
2009-11-07 11:30:38 +08:00
# define BIG 0x7f7f7f7f7f7f7f7fL
void test0 ( char c , short s , int i , long l , long long ll ) {
c = c ;
2010-07-10 02:18:35 +08:00
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}}
2009-11-07 11:30:38 +08:00
s = c ;
s = s ;
2010-07-10 02:18:35 +08:00
s = i ; // expected-warning {{implicit conversion loses integer precision}}
s = l ; // expected-warning {{implicit conversion loses integer precision}}
2009-11-07 11:30:38 +08:00
i = c ;
i = s ;
i = i ;
2010-07-10 02:18:35 +08:00
i = l ; // expected-warning {{implicit conversion loses integer precision}}
2009-11-07 11:30:38 +08:00
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 ;
2010-11-10 06:22:12 +08:00
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}}
2009-11-07 11:30:38 +08:00
s = ( char ) BIG ;
s = ( short ) BIG ;
2010-11-10 06:22:12 +08:00
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}}
2009-11-07 11:30:38 +08:00
i = ( char ) BIG ;
i = ( short ) BIG ;
i = ( int ) BIG ;
2010-11-10 06:22:12 +08:00
i = ( long ) BIG ; // expected-warning {{implicit conversion from 'long' to 'int' changes value}}
2009-11-07 11:30:38 +08:00
l = ( char ) BIG ;
l = ( short ) BIG ;
l = ( int ) BIG ;
l = ( long ) BIG ;
}
char test1 ( long long ll ) {
2010-07-10 02:18:35 +08:00
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}}
2009-11-07 11:30:38 +08:00
return ( char ) ll ;
2010-11-10 06:22:12 +08:00
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}}
2009-11-07 11:30:38 +08:00
return ( char ) BIG ;
}
short test2 ( long long ll ) {
2010-07-10 02:18:35 +08:00
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}}
2009-11-07 11:30:38 +08:00
return ( short ) ll ;
return ( char ) ll ;
2010-11-10 06:22:12 +08:00
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}}
2009-11-07 11:30:38 +08:00
return ( short ) BIG ;
return ( char ) BIG ;
}
int test3 ( long long ll ) {
2010-07-10 02:18:35 +08:00
return ( long long ) ll ; // expected-warning {{implicit conversion loses integer precision}}
return ( long ) ll ; // expected-warning {{implicit conversion loses integer precision}}
2009-11-07 11:30:38 +08:00
return ( int ) ll ;
return ( short ) ll ;
return ( char ) ll ;
2010-11-10 06:22:12 +08:00
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}}
2009-11-07 11:30:38 +08:00
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 ) {
2010-07-10 02:18:35 +08:00
takes_char ( v ) ; // expected-warning {{implicit conversion loses integer precision}}
2009-11-07 11:30:38 +08:00
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 ) {
2010-07-10 02:18:35 +08:00
takes_char ( v ) ; // expected-warning {{implicit conversion loses integer precision}}
takes_short ( v ) ; // expected-warning {{implicit conversion loses integer precision}}
2009-11-07 11:30:38 +08:00
takes_int ( v ) ;
takes_long ( v ) ;
takes_longlong ( v ) ;
takes_float ( v ) ;
takes_double ( v ) ;
takes_longdouble ( v ) ;
}
void test9 ( long v ) {
2010-07-10 02:18:35 +08:00
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}}
2009-11-07 11:30:38 +08:00
takes_long ( v ) ;
takes_longlong ( v ) ;
takes_float ( v ) ;
takes_double ( v ) ;
takes_longdouble ( v ) ;
}
void test10 ( long long v ) {
2010-07-10 02:18:35 +08:00
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}}
2009-11-07 11:30:38 +08:00
takes_long ( v ) ;
takes_longlong ( v ) ;
takes_float ( v ) ;
takes_double ( v ) ;
takes_longdouble ( v ) ;
}
void test11 ( float v ) {
2010-07-10 02:18:35 +08:00
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}}
2009-11-07 11:30:38 +08:00
takes_float ( v ) ;
takes_double ( v ) ;
takes_longdouble ( v ) ;
}
void test12 ( double v ) {
2010-07-10 02:18:35 +08:00
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}}
2009-11-07 11:30:38 +08:00
takes_double ( v ) ;
takes_longdouble ( v ) ;
}
void test13 ( long double v ) {
2010-07-10 02:18:35 +08:00
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}}
2009-11-07 11:30:38 +08:00
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 ) ;
}
2009-11-07 16:15:46 +08:00
void test15 ( char c ) {
c = c + 1 + c * 2 ;
2010-07-10 02:18:35 +08:00
c = ( short ) c + 1 + c * 2 ; // expected-warning {{implicit conversion loses integer precision}}
2009-11-07 16:15:46 +08:00
}
2009-11-12 06:52:37 +08:00
// PR 5422
extern void * test16_external ;
void test16 ( void ) {
2010-07-10 02:18:35 +08:00
int a = ( unsigned long ) & test16_external ; // expected-warning {{implicit conversion loses integer precision}}
2009-11-12 06:52:37 +08:00
}
2010-01-06 13:24:50 +08:00
// 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 ;
2010-07-10 02:18:35 +08:00
x = U . c ; // expected-warning {{implicit conversion loses integer precision}}
2010-01-06 13:24:50 +08:00
}
// 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 ) ;
}
2010-01-07 06:07:33 +08:00
// 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 ;
}
2010-02-12 02:52:49 +08:00
// <rdar://problem/7631400>
void test_7631400 ( void ) {
// This should show up despite the caret being inside a macro substitution
2010-11-10 06:22:12 +08:00
char s = LONG_MAX ; // expected-warning {{implicit conversion from 'long' to 'char' changes value}}
2010-02-12 02:52:49 +08:00
}
2010-02-24 03:22:29 +08:00
// <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 ) ;
}
2010-05-06 16:58:33 +08:00
// <rdar://problem/7904686>
void test_7904686 ( void ) {
const int i = - 1 ;
2010-07-10 02:18:35 +08:00
unsigned u1 = i ; // expected-warning {{implicit conversion changes signedness}}
u1 = i ; // expected-warning {{implicit conversion changes signedness}}
2010-05-06 16:58:33 +08:00
2010-07-10 02:18:35 +08:00
unsigned u2 = - 1 ; // expected-warning {{implicit conversion changes signedness}}
u2 = - 1 ; // expected-warning {{implicit conversion changes signedness}}
2010-05-06 16:58:33 +08:00
}
2010-10-08 10:01:28 +08:00
// <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}}
}
2011-02-22 10:45:07 +08:00
// <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'}}
2011-03-12 08:14:31 +08:00
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'}}
2011-02-22 10:45:07 +08:00
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 ;
}