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

Reply via email to