https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98599

--- Comment #13 from CVS Commits <cvs-commit at gcc dot gnu.org> ---
The master branch has been updated by David Malcolm <dmalc...@gcc.gnu.org>:

https://gcc.gnu.org/g:17f3c2b8ac477b07ca0aafbc7d74ba305dc1ee33

commit r11-8142-g17f3c2b8ac477b07ca0aafbc7d74ba305dc1ee33
Author: David Malcolm <dmalc...@redhat.com>
Date:   Mon Apr 12 21:13:40 2021 -0400

    gimple UIDs, LTO and -fanalyzer [PR98599]

    gimple.h has this comment for gimple's uid field:

      /* UID of this statement.  This is used by passes that want to
         assign IDs to statements.  It must be assigned and used by each
         pass.  By default it should be assumed to contain garbage.  */
      unsigned uid;

    and gimple_set_uid has:

       Please note that this UID property is supposed to be undefined at
       pass boundaries.  This means that a given pass should not assume it
       contains any useful value when the pass starts and thus can set it
       to any value it sees fit.

    which suggests that any pass can use the uid field as an arbitrary
    scratch space.

    PR analyzer/98599 reports a case where this error occurs in LTO mode:
      fatal error: Cgraph edge statement index out of range
    on certain inputs with -fanalyzer.

    The error occurs in the LTRANS phase after -fanalyzer runs in the
    WPA phase.  The analyzer pass writes to the uid fields of all stmts.

    The error occurs when LTRANS is streaming callgraph edges back in.
    The LTO format uses stmt uids to associate call stmts with callgraph
    edges between WPA and LTRANS.
    For example, in lto-cgraph.c, lto_output_edge writes out the
    gimple_uid, and input_edge reads it back in.

    lto_prepare_function_for_streaming has code to renumber the stmt UIDs
    when the code is streamed back out, but for some reason this isn't
    called for clones:
        307   /* Do body modifications needed for streaming before we fork out
        308      worker processes.  */
        309   FOR_EACH_FUNCTION_WITH_GIMPLE_BODY (node)
        310     if (!node->clone_of && gimple_has_body_p (node->decl))
        311       lto_prepare_function_for_streaming (node);

    Hence the combination of -fanalyzer and -flto will fail in LTRANS's
    stream-in if any function clones are encountered.

    It's not fully clear to me why this isn't done for clones, and what the
    correct fix should be to allow arbitrary changes to uids within WPA
    passes.

    In the meantime, this patch works around the issue by updating the
    analyzer to save and restore the UIDs, fixing the error.

    gcc/analyzer/ChangeLog:
            PR analyzer/98599
            * supergraph.cc (saved_uids::make_uid_unique): New.
            (saved_uids::restore_uids): New.
            (supergraph::supergraph): Replace assignments to stmt->uid with
            calls to m_stmt_uids.make_uid_unique.
            (supergraph::~supergraph): New.
            * supergraph.h (class saved_uids): New.
            (supergraph::~supergraph): New decl.
            (supergraph::m_stmt_uids): New field.

    gcc/testsuite/ChangeLog:
            PR analyzer/98599
            * gcc.dg/analyzer/pr98599-a.c: New test.
            * gcc.dg/analyzer/pr98599-b.c: New test.

Reply via email to