------- Comment #3 from jakub at gcc dot gnu dot org  2008-09-01 12:40 -------
This is a C++ FE bug.  Shorter testcase:
enum E { E0 = 0, E1 = 'E' };

struct S
{
  E s0 : 8;
  enum E foo (bool, E);
};

E S::foo (bool a, E b)
{
  return a ? s0 : b;
}

The bug is IMHO in build_conditional_expr.  One of:
  arg2_type = unlowered_expr_type (arg2);
  arg3_type = unlowered_expr_type (arg3);
calls returns a different type from TREE_TYPE (argX), as that's bitfield
COMPONENT_REF.  Neither of the types are void and neither is class type, so
nothing is converted first and we reach:
  /* [expr.cond]

     If the second and third operands are lvalues and have the same
     type, the result is of that type and is an lvalue.  */
  if (real_lvalue_p (arg2)
      && real_lvalue_p (arg3)
      && same_type_p (arg2_type, arg3_type))
    {
      result_type = arg2_type;
      goto valid_operands;
    }
where arg2_type is the same as arg3_type, but TREE_TYPE (arg2) != TREE_TYPE
(arg3), not even useless type conversion, and at valid_operands we build it
right away as COND_EXPR.  Can x ? bitfield : val be even considered as valid
lvalue by C++ standard (I mean e.g. bitfield can have different number of bits
from val)?  If we don't shortcut here, force_rvalue is called on both arguments
and that will call the needed convert_bitfield_to_declared_type somewhere.
E.g.:
--- call.c.jj2008-08-29 18:23:10.000000000 +0200
+++ call.c2008-09-01 14:27:24.000000000 +0200
@@ -3596,7 +3596,9 @@ build_conditional_expr (tree arg1, tree 
      type, the result is of that type and is an lvalue.  */
   if (real_lvalue_p (arg2)
       && real_lvalue_p (arg3)
-      && same_type_p (arg2_type, arg3_type))
+      && same_type_p (arg2_type, arg3_type)
+      && is_bitfield_expr_with_lowered_type (arg2) == NULL_TREE
+      && is_bitfield_expr_with_lowered_type (arg3) == NULL_TREE)
     {
       result_type = arg2_type;
       goto valid_operands;
cures this testcase, but I'm not sure if it is correct from C++ standard POV.


-- 

jakub at gcc dot gnu dot org changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |jason at gcc dot gnu dot org


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=37146

Reply via email to