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]

Re: Fix for regression in gcc.c-torture/execute/20011114-1.c


On Dec  2, 2001, Richard Henderson <rth@redhat.com> wrote:

> On Sun, Dec 02, 2001 at 05:17:31PM -0200, Alexandre Oliva wrote:
>> Would it be reasonable to have DECL_ABSTRACT_ORIGIN(newdecl) point to
>> olddecl, so that the tree inliner could then get DECL_INITIAL from the
>> olddecl?

> Um, I dunno.  Doesn't that have special meaning to debug info?

Well, the documentation says:

/* For any sort of a ..._DECL node, this points to the original (abstract)
   decl node which this decl is an instance of, or else it is NULL indicating
   that this decl is not an instance of some other decl.  For example,
   in a nested declaration of an inline function, this points back to the
   definition.  */
#define DECL_ABSTRACT_ORIGIN(NODE) (DECL_CHECK (NODE)->decl.abstract_origin)

so it seems that the fact that we don't set it as I had suggested is a
bug.

The patch below arranges for this setting to be applied to nested
inline functions, and arranges for get_callee_fndecl to use
DECL_ABSTRACT_ORIGIN should DECL_INITIAL be NULL.

I looked for similar needs in the C++ front-end, but it manages
duplicate declarations quite differently, in such a way that
DECL_INITIAL is copied even in this case, so I haven't changed it.

This bootstraps and doesn't introduce any regressions on
athlon-pc-linux-gnu, and gets c-torture/execute/930603-1.c to have
fx() inlined into main().  Ok to install?

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

	* c-decl.c (duplicate_decls): Revert rth's patch.  If newdecl
	is in a different binding level, get its abstract origin to be
	olddecl.
	* tree-inline.c (expand_call_inline): Move DECL_INITIAL sanity
	check earlier.
	* tree.c (get_callee_fndecl): Follow DECL_ABSTRACT_ORIGIN if
	DECL_INITIAL is NULL.

Index: gcc/c-decl.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/c-decl.c,v
retrieving revision 1.275
diff -u -p -r1.275 c-decl.c
--- gcc/c-decl.c 2001/12/02 19:18:22 1.275
+++ gcc/c-decl.c 2001/12/02 20:18:39
@@ -2019,14 +2019,15 @@ duplicate_decls (newdecl, olddecl, diffe
 	     DECL_INITIAL, so that we don't accidentally change function
 	     declarations into function definitions.  */
 	  if (! different_binding_level)
-	    {
-	      DECL_INITIAL (newdecl) = DECL_INITIAL (olddecl);
-	      DECL_SAVED_TREE (newdecl) = DECL_SAVED_TREE (olddecl);
-	    }
+	    DECL_INITIAL (newdecl) = DECL_INITIAL (olddecl);
 	  DECL_SAVED_INSNS (newdecl) = DECL_SAVED_INSNS (olddecl);
+	  DECL_SAVED_TREE (newdecl) = DECL_SAVED_TREE (olddecl);
 	  DECL_ARGUMENTS (newdecl) = DECL_ARGUMENTS (olddecl);
 	  if (DECL_INLINE (newdecl))
-	    DECL_ABSTRACT_ORIGIN (newdecl) = DECL_ABSTRACT_ORIGIN (olddecl);
+	    DECL_ABSTRACT_ORIGIN (newdecl)
+	      = (different_binding_level
+		 ? DECL_ORIGIN (olddecl)
+		 : DECL_ABSTRACT_ORIGIN (olddecl));
 	}
     }
   if (different_binding_level)
Index: gcc/tree-inline.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/tree-inline.c,v
retrieving revision 1.10
diff -u -p -r1.10 tree-inline.c
--- gcc/tree-inline.c 2001/11/28 09:47:23 1.10
+++ gcc/tree-inline.c 2001/12/02 20:18:40
@@ -864,6 +864,10 @@ expand_call_inline (tp, walk_subtrees, d
   id->ret_label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE);
   DECL_CONTEXT (id->ret_label) = VARRAY_TREE (id->fns, 0);
 
+  if (! DECL_INITIAL (fn)
+      || TREE_CODE (DECL_INITIAL (fn)) != BLOCK)
+    abort ();
+
   /* Create a block to put the parameters in.  We have to do this
      after the parameters have been remapped because remapping
      parameters is different from remapping ordinary variables.  */
@@ -894,9 +898,6 @@ expand_call_inline (tp, walk_subtrees, d
   /* Close the block for the parameters.  */
   scope_stmt = build_stmt (SCOPE_STMT, DECL_INITIAL (fn));
   SCOPE_NO_CLEANUPS_P (scope_stmt) = 1;
-  if (! DECL_INITIAL (fn)
-      || TREE_CODE (DECL_INITIAL (fn)) != BLOCK)
-    abort ();
   remap_block (scope_stmt, NULL_TREE, id);
   STMT_EXPR_STMT (expr)
     = chainon (STMT_EXPR_STMT (expr), scope_stmt);
Index: gcc/tree.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/tree.c,v
retrieving revision 1.223
diff -u -p -r1.223 tree.c
--- gcc/tree.c 2001/12/02 14:38:07 1.223
+++ gcc/tree.c 2001/12/02 20:18:40
@@ -4378,7 +4378,14 @@ get_callee_fndecl (call)
      that `f' is being called.  */
   if (TREE_CODE (addr) == ADDR_EXPR
       && TREE_CODE (TREE_OPERAND (addr, 0)) == FUNCTION_DECL)
-    return TREE_OPERAND (addr, 0);
+    {
+      addr = TREE_OPERAND (addr, 0);
+
+      if (! DECL_INITIAL (addr) && DECL_ABSTRACT_ORIGIN (addr))
+	addr = DECL_ABSTRACT_ORIGIN (addr);
+
+      return addr;
+    }
 
   /* We couldn't figure out what was being called.  */
   return NULL_TREE;

-- 
Alexandre Oliva   Enjoy Guarana', see http://www.ic.unicamp.br/~oliva/
Red Hat GCC Developer                  aoliva@{cygnus.com, redhat.com}
CS PhD student at IC-Unicamp        oliva@{lsd.ic.unicamp.br, gnu.org}
Free Software Evangelist    *Please* write to mailing lists, not to me

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