This is the mail archive of the gcc-bugs@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]

[Bug middle-end/46823] [4.6 Regression] ICE: edge points to wrong declaration


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=46823

--- Comment #16 from Martin Jambor <jamborm at gcc dot gnu.org> 2011-01-10 20:34:14 UTC ---
The problem seems to be a different one.  During IPA decision making
we decide to clone a function and the call graph node of the original
one is then removed as unreachable an unnecessary.  However, its
declaration stays in the IL until the transformation phase where
expand_call_inline calls cgraph_node() on it which creates a new,
seemingly entirely separate call graph node.  This is then what the
verifier gets for the decl, cannot find any relation between what the
edge points to and the new node and errors out.

We cannot simply replace the call to cgraph_node with cgraph_get_node
and bail out if it returns NULL because the call is supposed to be
inlined and this is then asserted later.  The information about the
call just happens to be stored in the call graph edge and the fndecl
in the gimple statement is not necessarily relevant at all.  So the
fix which I am testing at the moment just extracts the target
declaration from the call graph, bypassing whatever is in the
statement.

I will submit this patch tomorrow if it passes bootstrap and testing.


2011-01-10  Martin Jambor  <mjambor@suse.cz>

    PR middle-end/46823
    * tree-inline.c (expand_call_inline): Get fndecl from call graph edge.

Index: icln/gcc/tree-inline.c
===================================================================
--- icln.orig/gcc/tree-inline.c
+++ icln/gcc/tree-inline.c
@@ -3783,14 +3783,19 @@ expand_call_inline (basic_block bb, gimp
   if (gimple_code (stmt) != GIMPLE_CALL)
     goto egress;

+  /* Objective C and fortran still calls tree_rest_of_compilation directly.
+     Kill this check once this is fixed.  */
+  if (!id->dst_node->analyzed)
+    goto egress;
+
+  cg_edge = cgraph_edge (id->dst_node, stmt);
+  gcc_checking_assert (cg_edge);
   /* First, see if we can figure out what function is being called.
      If we cannot, then there is no hope of inlining the function.  */
-  fn = gimple_call_fndecl (stmt);
-  if (!fn)
+  if (cg_edge->indirect_unknown_callee)
     goto egress;
-
-  /* Turn forward declarations into real ones.  */
-  fn = cgraph_node (fn)->decl;
+  fn = cg_edge->callee->decl;
+  gcc_checking_assert (fn);

   /* If FN is a declaration of a function in a nested scope that was
      globally declared inline, we don't set its DECL_INITIAL.
@@ -3804,13 +3809,6 @@ expand_call_inline (basic_block bb, gimp
       && gimple_has_body_p (DECL_ABSTRACT_ORIGIN (fn)))
     fn = DECL_ABSTRACT_ORIGIN (fn);

-  /* Objective C and fortran still calls tree_rest_of_compilation directly.
-     Kill this check once this is fixed.  */
-  if (!id->dst_node->analyzed)
-    goto egress;
-
-  cg_edge = cgraph_edge (id->dst_node, stmt);
-
   /* First check that inlining isn't simply forbidden in this case.  */
   if (inline_forbidden_into_p (cg_edge->caller->decl, cg_edge->callee->decl))
     goto egress;


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