------- 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