------- Additional Comments From jakub at gcc dot gnu dot org  2005-01-10 11:28 
-------
Yes, my patch clearly triggers this (changing silent miscompilation of the
code into an ICE).
The problem is that common_type doesn't handle ENUMERAL_TYPEs, so probably
shorten_compare should made sure it doesn't get passed down.
The difference is that while previously shorten_compare was passed 
CONVERT_EXPRs,
created in convert.c's
          /* If the precision of the EXPR's type is K bits and the
             destination mode has more bits, and the sign is changing,
             it is not safe to use a NOP_EXPR.  For example, suppose
             that EXPR's type is a 3-bit unsigned integer type, the
             TYPE is a 3-bit signed integer type, and the machine mode
             for the types is 8-bit QImode.  In that case, the
             conversion necessitates an explicit sign-extension.  In
             the signed-to-unsigned case the high-order bits have to
             be cleared.  */
          if (TYPE_UNSIGNED (type) != TYPE_UNSIGNED (TREE_TYPE (expr))
              && (TYPE_PRECISION (TREE_TYPE (expr))
                  != GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (expr)))))
            code = CONVERT_EXPR;
          else
            code = NOP_EXPR;

          return build1 (code, type, expr);
now, when the mode is fixed, we pass NOP_EXPR.  So, before my patch 
primop{0,1}'s
type was int while now it is that enum __attribute__((mode(byte))).

Now, C++ common_type handles ENUMERAL_TYPEs, so I don't think it is appropriate
to special case ENUMERAL_TYPEs in shorten_compare which is shared between
C/C++/ObjC.  So perhaps add code to handle ENUMERAL_TYPEs in C common_type?

-- 


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

Reply via email to