The following fixes C++ testsuite FAILs. First in fold_binary we should delay the dispatch to generic_simplify until after const OP const folding which generic_simplify isn't supposed to do. (I note that neither fold_unary nor fold_ternary has such clear const operand path...)
Second, the C++ FE folds too early and some testcases expect to detect sizeof (&a) + 0 in some way (didn't look). Wrapping the result in a NON_LVALUE_EXPR works around the issue (though certainly sizeof (&a) shouldn't be considered an lvalue by maybe_lvalue_p). Full testing pending on x86_64-unknown-linux-gnu. Richard. 2014-08-26 Richard Biener <rguent...@suse.de> * fold-const.c (fold_binary_loc): Move dispatch to generic_simplfy after folding of operations on two constants. * match-constant-folding.pd (x + 0 -> x): Wrap result in a NON_LVALUE_EXPR to account for the C++ frontend folding too early, avoding some spurious testsuite FAILs. Index: gcc/fold-const.c =================================================================== --- gcc/fold-const.c (revision 214490) +++ gcc/fold-const.c (working copy) @@ -10068,11 +10067,6 @@ fold_binary_loc (location_t loc, && op0 != NULL_TREE && op1 != NULL_TREE); - extern tree generic_simplify (enum tree_code, tree, tree, tree); - tem = generic_simplify (code, type, op0, op1); - if (tem) - return tem; - arg0 = op0; arg1 = op1; @@ -10130,6 +10124,11 @@ fold_binary_loc (location_t loc, } } + extern tree generic_simplify (enum tree_code, tree, tree, tree); + tem = generic_simplify (code, type, op0, op1); + if (tem) + return tem; + /* If this is a commutative operation, and ARG0 is a constant, move it to ARG1 to reduce the number of tests below. */ if (commutative_tree_code (code) Index: gcc/match-constant-folding.pd =================================================================== --- gcc/match-constant-folding.pd (revision 214490) +++ gcc/match-constant-folding.pd (working copy) @@ -20,7 +20,17 @@ along with GCC; see the file COPYING3. (for op in plus pointer_plus minus bit_ior bit_xor (simplify (op @0 integer_zerop) - @0)) +#if GENERIC + /* ??? fold_binary adds non_lvalue here and "fixes" the C++ + run of Wsizeof-pointer-memaccess1.c, preserving enough of + sizeof (&a) + 0 because sizeof (&a) is maybe_lvalue_p () + for no good reason. The C frontend is fine as it doesn't + fold too early. */ + (non_lvalue @0) +#else + @0 +#endif + )) (simplify (minus @0 @0)