2014-08-12 Thomas Preud'homme PR middle-end/62103 * gimple-fold.c (fold_ctor_reference): Don't fold in presence of bitfields, that is when size doesn't match the size of type or the size of the constructor. * gcc.c-torture/execute/bitfld-6.c: New test. --- gcc/gimple-fold.c (revision 213845) +++ gcc/gimple-fold.c (revision 213846) @@ -4355,8 +4355,10 @@ fold_ctor_reference (tree type, tree cto result. */ if (!AGGREGATE_TYPE_P (TREE_TYPE (ctor)) && !offset /* VIEW_CONVERT_EXPR is defined only for matching sizes. */ - && operand_equal_p (TYPE_SIZE (type), - TYPE_SIZE (TREE_TYPE (ctor)), 0)) + && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST + && TREE_CODE (TYPE_SIZE (TREE_TYPE (ctor))) == INTEGER_CST + && !compare_tree_int (TYPE_SIZE (type), size) + && !compare_tree_int (TYPE_SIZE (TREE_TYPE (ctor)), size)) { ret = canonicalize_constructor_val (unshare_expr (ctor), from_decl); ret = fold_unary (VIEW_CONVERT_EXPR, type, ret); --- gcc/testsuite/gcc.c-torture/execute/bitfld-6.c (revision 0) +++ gcc/testsuite/gcc.c-torture/execute/bitfld-6.c (revision 213846) @@ -0,0 +1,23 @@ +union U +{ + const int a; + unsigned b : 20; +}; + +static union U u = { 0x12345678 }; + +/* Constant folding used to fail to account for endianness when folding a + union. */ + +int +main (void) +{ +#ifdef __BYTE_ORDER__ +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ + return u.b - 0x45678; +#else + return u.b - 0x12345; +#endif +#endif + return 0; +}