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 #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.


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