This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

tree-inline mishandles ADDR_EXPRs


The tree inliner doesn't handle passing addresses of local variables
to inlined functions correctly.

In the case of one function passing the address of a local variable as
an argument to another function, if this latter function happens to be
inlined, if we map the parameter to the ADDR_EXPR (as opposed to
creating a VAR_DECL and assigning the ADDR_EXPR to it), we may end up
mapping the variable within the ADDR_EXPR to another decl, setting it
apart from the variable whose address was actually passed as an
argument.

As far as I can tell, we never do this in normal cases, because
auto_var_in_fn_p doesn't hold for the passed-in variable.  Unless, as
in PR16951, we have a function inlined into itself, and it takes a
pointer to a variable that is automatic in the caller.  In this case,
the predicate holds, so we don't want to apply the direct-binding
optimization, otherwise we wouldn't be able to tell references to the
caller variable from references within the callee.

This patch makes this change, and goes a bit further, in that, if we
apply the optimization (i.e., not in the self-inlining case), we make
sure the base variable of the ADDR_EXPR is mapped to itself.  Now I'm
having second thoughts on whether we actually need this (I hadn't
realized the auto_var_in_fn_p would prevent the remapping before
composing this e-mail).  Maybe all we need is to avoid the
optimization for self-inlining.  It would probably have seemed far
more broken otherwise.

Anyhow, here's the patch that succeeded bootstrapping on
x86_64-linux-gnu.  I'll start bootstrapping and testing a simplified
version now and report back later.  Is this, or the simplified version
(that doesn't do the self-remapping), ok to install?

Index: gcc/ChangeLog
from  Alexandre Oliva  <aoliva@redhat.com>

	PR tree-optimization/16951
	* tree-inline.c (setup_one_parameter): Don't directly map a
	parameter to the address of another variable of the same
	function.

Index: gcc/tree-inline.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-inline.c,v
retrieving revision 1.156
diff -u -p -r1.156 tree-inline.c
--- gcc/tree-inline.c 9 Dec 2004 10:54:36 -0000 1.156
+++ gcc/tree-inline.c 11 Dec 2004 02:11:58 -0000
@@ -681,8 +681,44 @@ setup_one_parameter (inline_data *id, tr
       if (is_gimple_min_invariant (value)
 	  && lang_hooks.types_compatible_p (TREE_TYPE (value), TREE_TYPE (p)))
 	{
-	  insert_decl_map (id, p, value);
-	  return;
+	  if (TREE_CODE (value) == ADDR_EXPR)
+	    {
+	      tree var = get_base_address (TREE_OPERAND (value, 0));
+	      
+	      /* We have to be very careful about ADDR_EXPR.  Make
+		 sure the base variable isn't a local variable of the
+		 inlined function (e.g., when doing recursive
+		 inlining, direct or mutually-recursive or whatever,
+		 which is why we don't just test whether fn ==
+		 current_function_decl).  When it isn't, we can still
+		 perform the optimization, but we have to make sure
+		 that, if we had a complex expression, we remap the
+		 base variable to itself, otherwise we'll end up
+		 creating a separate variable for it.  */
+
+	      if (var && (TREE_CODE (var) == VAR_DECL
+			  || TREE_CODE (var) == PARM_DECL
+			  || TREE_CODE (var) == LABEL_DECL)
+		  && ! lang_hooks.tree_inlining.auto_var_in_fn_p (var, fn))
+		{
+		  /* If they're the same, mapping p to value will
+		     already take care of mapping var to itself.  */
+		  if (value != var)
+		    insert_decl_map (id, var, var);
+
+		  insert_decl_map (id, p, value);
+		  return;
+		}
+
+	      /* If the above failed, we have to create copy the decl,
+		 which we do below, instead of simply remapping as in
+		 the else clause.  */
+	    }
+	  else
+	    {
+	      insert_decl_map (id, p, value);
+	      return;
+	    }
 	}
     }
 
-- 
Alexandre Oliva             http://www.ic.unicamp.br/~oliva/
Red Hat Compiler Engineer   aoliva@{redhat.com, gcc.gnu.org}
Free Software Evangelist  oliva@{lsd.ic.unicamp.br, gnu.org}

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]