This fixes an issue that showed up when regimplifying a call with a WITH_SIZE_EXPR for one of its arguments. At the moment we can end up trying to make a temporary and aborting because we don't know what size it ought to be. The problem is that we call gimplify_expr with the wrong predicate: gimplify_arg uses is_gimple_lvalue in some cases instead of is_gimple_val, and regimplification needs to match that.

Bootstrapped and tested on x86_64-linux, ok?


Bernd
commit c1296ac4f4e7e8f0fb9c87d71ca8194a8eac0067
Author: Bernd Schmidt <ber...@codesourcery.com>
Date:   Wed Jun 11 18:41:09 2014 +0200

    Fix an issue with regimplification.
    
    	gcc/
    	* gimplify-me.c (gimple_regimplify_operands): Ensure that for
    	calls we use the same predicate as in gimplify_arg.

diff --git a/gcc/gimplify-me.c b/gcc/gimplify-me.c
index 467ec6c..05eaeb0 100644
--- a/gcc/gimplify-me.c
+++ b/gcc/gimplify-me.c
@@ -245,7 +245,17 @@ gimple_regimplify_operands (gimple stmt, gimple_stmt_iterator *gsi_p)
 	      gimplify_expr (&op, &pre, NULL, is_gimple_call_addr, fb_rvalue);
 	    }
 	  else
-	    gimplify_expr (&op, &pre, NULL, is_gimple_val, fb_rvalue);
+	    {
+	      bool (*test) (tree) = is_gimple_val;
+	      fallback_t fb = fb_rvalue;
+	      if (is_gimple_call (stmt)
+		  && !is_gimple_reg_type (TREE_TYPE (op)))
+		{
+		  test = is_gimple_lvalue;
+		  fb = fb_either;
+		}
+	      gimplify_expr (&op, &pre, NULL, test, fb);
+	    }
 	  gimple_set_op (stmt, i - 1, op);
 	}
       if (is_gimple_assign (stmt)

Reply via email to