Fix PR tree-optimization/54986

Submitted by Eric Botcazou on Nov. 5, 2012, 9:16 p.m.

Details

Message ID 6178668.1GMYr7Gxhl@polaris
State New
Headers show

Commit Message

Eric Botcazou Nov. 5, 2012, 9:16 p.m.
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  <ebotcazou@adacore.com>

	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  <ebotcazou@adacore.com>

	* g++.dg/torture/20121005-1.C: New test.

Comments

Jakub Jelinek Nov. 5, 2012, 9:25 p.m.
On Mon, Nov 05, 2012 at 10:16:31PM +0100, Eric Botcazou wrote:
> Bootstrapped/regtested on x86_64-suse-linux, OK for mainline and 4.7 branch?
> 
> 
> 2012-11-05  Eric Botcazou  <ebotcazou@adacore.com>
> 
> 	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  <ebotcazou@adacore.com>
> 
> 	* g++.dg/torture/20121005-1.C: New test.

Ok, thanks.

	Jakub

Patch hide | download patch | download mbox

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.