This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug middle-end/46823] [4.6 Regression] ICE: edge points to wrong declaration
- From: "rguenth at gcc dot gnu.org" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: Thu, 13 Jan 2011 10:35:46 +0000
- Subject: [Bug middle-end/46823] [4.6 Regression] ICE: edge points to wrong declaration
- Auto-submitted: auto-generated
- References: <bug-46823-4@http.gcc.gnu.org/bugzilla/>
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=46823
--- Comment #19 from Richard Guenther <rguenth at gcc dot gnu.org> 2011-01-13 10:35:33 UTC ---
(In reply to comment #16)
> 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;
Err - I'm not sure what this
/* Turn forward declarations into real ones. */
fn = cgraph_node (fn)->decl;
is about at all. At least the comment doesn't make any sense to me.
But yes, the above makes sense to me.