[Bug lto/59543] [4.9 Regression] lto1: fatal error: Cgraph edge statement index out of range

jakub at gcc dot gnu.org gcc-bugzilla@gcc.gnu.org
Mon Feb 17 15:28:00 GMT 2014


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

Jakub Jelinek <jakub at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|UNCONFIRMED                 |NEW
   Last reconfirmed|                            |2014-02-17
                 CC|                            |jakub at gcc dot gnu.org
     Ever confirmed|0                           |1

--- Comment #6 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
Isn't it an ODR violation if UnicodeString::extractBetween inline has different
definition between unorm.ii and uniset.ii?  In any case, the bug reported here
seems to be unrelated to that.

Anyway, from what I see, here is what happens:
1) uniset.ii UnicodeString::extractBetween is being streamed by cc1plus,
including debug stmts, so gets high uid (in my case uid 45 and lto_stmt_uid for
the corresponding edge is streamed as 46 (+1)).

2) now, when the first lto1 invocation happens (is that WPA pass, right), it
first reads all the stmts, then drop debug stmts after assinging uids (ok)

3) next:
#3  0x000000000064790c in build_function_decl_skip_args
(orig_decl=0x7ffff1a1ac00, args_to_skip=0x7ffff1a2d240, skip_return=false)
    at ../../gcc/cgraphclones.c:375
#4  0x0000000000647bef in cgraph_create_virtual_clone (old_node=0x7ffff1a2b668,
redirect_callers=..., tree_map=0x7ffff1a33488, 
    args_to_skip=0x7ffff1a2d240, suffix=0x1590c10 "constprop") at
../../gcc/cgraphclones.c:433
#5  0x00000000011579d9 in create_specialized_node (node=0x7ffff1a2b668,
known_vals=..., aggvals=0x0, callers=...) at ../../gcc/ipa-cp.c:2790
#6  0x0000000001159755 in decide_whether_version_node (node=0x7ffff1a2b668) at
../../gcc/ipa-cp.c:3545
versions the UnicodeString::extractBetween function, but nothing allocates
DECL_STRUCT_FUNCTION for it - it supposedly inherits the body of the master

4) then output_function is called on the original UnicodeString::extractBetween
(not the clone), this reassigns stmt uids, and as 2) dropped the debug stmts
already, the call stmt in there gets much smaller uid (25)

5) finally, lto_output_edge is called, and does:
      uid = (!gimple_has_body_p (edge->caller->decl)
         ? edge->lto_stmt_uid : gimple_uid (edge->call_stmt) + 1);
but here edge->caller->decl is the clone of UnicodeString::extractBetween,
rather than original, it has NULL DECL_STRUCT_FUNCTION and thus
gimple_has_body_p returns false for it and it happily uses the now completely
out of bound lto_stmt_uid (46), rather than the right one (25+1).

Now, I wonder if it isn't always safe to use gimple_uid (edge->call_stmt) + 1
here if edge->call_stmt is non-NULL, or e.g. if we need to look through
clone_of pointers to find ultimate clone and check gimple_has_body_p on that,
or loop through clone_of pointers and stop on the first one where
gimple_has_body_p returns true, something else?

Honza?



More information about the Gcc-bugs mailing list