From patchwork Mon Nov 5 21:16:31 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: Fix PR tree-optimization/54986 Date: Mon, 05 Nov 2012 11:16:31 -0000 From: Eric Botcazou X-Patchwork-Id: 197309 Message-Id: <6178668.1GMYr7Gxhl@polaris> To: gcc-patches@gcc.gnu.org Hi, this is a regression present on the 4.7 branch and caused by my fix for another regression: http://gcc.gnu.org/ml/gcc-patches/2012-07/msg00825.html It turns out that canonicalize_constructor_val has side effects: on the 4.7 branch, it calls add_referenced_var on the base variable of an address (it does something similar on mainline) and not calling it for the testcase leads to a segfault later because the var_ann of a global variable doesn't exist. So the STRIP_NOPS is needed for the pattern matching code to work. That's why the attached patch adds it back but makes it so that an appropriate cast is added back at the end if necessary. Bootstrapped/regtested on x86_64-suse-linux, OK for mainline and 4.7 branch? 2012-11-05 Eric Botcazou PR tree-optimization/54986 * gimple-fold.c (canonicalize_constructor_val): Strip again all no-op conversions on entry but add them back on exit if needed. 2012-11-05 Eric Botcazou * g++.dg/torture/20121005-1.C: New test. Index: gimple-fold.c =================================================================== --- gimple-fold.c (revision 193090) +++ gimple-fold.c (working copy) @@ -139,7 +139,8 @@ can_refer_decl_in_current_unit_p (tree d tree canonicalize_constructor_val (tree cval, tree from_decl) { - STRIP_USELESS_TYPE_CONVERSION (cval); + tree orig_cval = cval; + STRIP_NOPS (cval); if (TREE_CODE (cval) == POINTER_PLUS_EXPR && TREE_CODE (TREE_OPERAND (cval, 1)) == INTEGER_CST) { @@ -182,8 +183,12 @@ canonicalize_constructor_val (tree cval, /* Fixup types in global initializers. */ if (TREE_TYPE (TREE_TYPE (cval)) != TREE_TYPE (TREE_OPERAND (cval, 0))) cval = build_fold_addr_expr (TREE_OPERAND (cval, 0)); + + if (!useless_type_conversion_p (TREE_TYPE (orig_cval), TREE_TYPE (cval))) + cval = fold_convert (TREE_TYPE (orig_cval), cval); + return cval; } - return cval; + return orig_cval; } /* If SYM is a constant variable with known value, return the value.