diff mbox

Fix prepare_call_arguments for types passed by reference (PR middle-end/48152)

Message ID 20110316231635.GN30899@tyan-ft48-01.lab.bos.redhat.com
State New
Headers show

Commit Message

Jakub Jelinek March 16, 2011, 11:16 p.m. UTC
Hi!

Bootstrap currently fails on mingw, because
targetm.calls.function_arg_advance has various asserts and doesn't
like being passed parameters that should have been passed by reference.
prepare_call_arguments code just tried to match up what types
arguments have and if there is no match, just gives up for the references,
so it wasn't creating wrong debug info, just sometimes incomplete.
But when backend ices on it, we have to try harder to get it right.

The following should fix it, bootstrapped/regtested on x86_64-linux and
i686-linux and tested with a cross on the testcase.  Ok for trunk?

2011-03-17  Jakub Jelinek  <jakub@redhat.com>

	PR middle-end/48152
	* var-tracking.c (prepare_call_arguments): If argument needs to be
	passed by reference, adjust argtype and mode.


	Jakub

Comments

Richard Henderson March 17, 2011, 2:52 p.m. UTC | #1
On 03/16/2011 04:16 PM, Jakub Jelinek wrote:
> 	PR middle-end/48152
> 	* var-tracking.c (prepare_call_arguments): If argument needs to be
> 	passed by reference, adjust argtype and mode.

Ok.


r~
diff mbox

Patch

--- gcc/var-tracking.c.jj	2011-03-16 18:30:12.000000000 +0100
+++ gcc/var-tracking.c	2011-03-16 20:12:06.000000000 +0100
@@ -5732,11 +5732,18 @@  prepare_call_arguments (basic_block bb, 
 	  call_arguments = gen_rtx_EXPR_LIST (VOIDmode, item, call_arguments);
 	if (t && t != void_list_node)
 	  {
-	    enum machine_mode mode = TYPE_MODE (TREE_VALUE (t));
-	    rtx reg = targetm.calls.function_arg (&args_so_far, mode,
-						  TREE_VALUE (t), true);
-	    if (TREE_CODE (TREE_VALUE (t)) == REFERENCE_TYPE
-		&& INTEGRAL_TYPE_P (TREE_TYPE (TREE_VALUE (t)))
+	    tree argtype = TREE_VALUE (t);
+	    enum machine_mode mode = TYPE_MODE (argtype);
+	    rtx reg;
+	    if (pass_by_reference (&args_so_far, mode, argtype, true))
+	      {
+		argtype = build_pointer_type (argtype);
+		mode = TYPE_MODE (argtype);
+	      }
+	    reg = targetm.calls.function_arg (&args_so_far, mode,
+					      argtype, true);
+	    if (TREE_CODE (argtype) == REFERENCE_TYPE
+		&& INTEGRAL_TYPE_P (TREE_TYPE (argtype))
 		&& reg
 		&& REG_P (reg)
 		&& GET_MODE (reg) == mode
@@ -5747,7 +5754,7 @@  prepare_call_arguments (basic_block bb, 
 		&& item)
 	      {
 		enum machine_mode indmode
-		  = TYPE_MODE (TREE_TYPE (TREE_VALUE (t)));
+		  = TYPE_MODE (TREE_TYPE (argtype));
 		rtx mem = gen_rtx_MEM (indmode, x);
 		cselib_val *val = cselib_lookup (mem, indmode, 0, VOIDmode);
 		if (val && cselib_preserved_value_p (val))
@@ -5784,7 +5791,7 @@  prepare_call_arguments (basic_block bb, 
 		  }
 	      }
 	    targetm.calls.function_arg_advance (&args_so_far, mode,
-						TREE_VALUE (t), true);
+						argtype, true);
 	    t = TREE_CHAIN (t);
 	  }
       }