This comes from PR 34389 and it only fails in C++. There is already a testcase:
trunk/gcc/testsuite/g++.dg/warn/Wconversion-pr34389.C short mask1(short x) { short y = 0x7fff; return x & y; /* { dg-bogus "conversion" "conversion" { xfail *-*-* } 8 } */ } In C, build_binary_op constructs: <bit_and_expr 0x2aaaab068200 type <integer_type 0x2aaaab08e540 short int HI size <integer_cst 0x2aaaab08c930 constant 16> unit size <integer_cst 0x2aaaab08c960 constant 2> arg 0 <parm_decl 0x2aaaab095240 x type <integer_type 0x2aaaab08e540 short int> arg 1 <var_decl 0x2aaaab161280 y type <integer_type 0x2aaaab08e540 short int> while C++ builds: <bit_and_expr 0x2aaaab21df80 type <integer_type 0x2aaaab08e6c0 int public SI size <integer_cst 0x2aaaab08ca20 constant 32> unit size <integer_cst 0x2aaaab08c690 constant 4> arg 0 <nop_expr 0x2aaaab21df00 type <integer_type 0x2aaaab08e6c0 int> arg 0 <parm_decl 0x2aaaab095a20 x type <integer_type 0x2aaaab08e540 short int> arg 1 <nop_expr 0x2aaaab21df40 type <integer_type 0x2aaaab08e6c0 int> arg 0 <var_decl 0x2aaaab238000 y type <integer_type 0x2aaaab08e540 short int> The difference is in shorten_binary_op->common_type. In C, it returns short int, while in C++ it returns int. If it returned short int in C++, I think it will avoid warning. A more robust fix would be to make conversion_warning smart enough to handle the C++ expression. Not sure how to do that, though. -- Summary: [C++ only] Wconversion warns for short y = 0x7fff; short z = (short) x & y; Product: gcc Version: unknown Status: UNCONFIRMED Keywords: diagnostic Severity: normal Priority: P3 Component: c++ AssignedTo: unassigned at gcc dot gnu dot org ReportedBy: manu at gcc dot gnu dot org http://gcc.gnu.org/bugzilla/show_bug.cgi?id=37004