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

Nathaniel Shead <nshead at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |nshead at gcc dot gnu.org

--- Comment #8 from Nathaniel Shead <nshead at gcc dot gnu.org> ---
The root cause is that 'sort_cluster' is not correctly ordering the
dependencies; both the element_t specialisation and the reverse_adaptor::first
function decl depend on each other, but by streaming element_t first it ends up
trying to stream itself recursively as part of calculating its own merge key,
which apart from the checking ICE will also cause issues on stream-in.

There is a comment in the source file describing this very issue:

  /* Now rewrite entries [0,lwm), in the dependency order we
     discovered.  Usually each entity is in its own cluster.  Rarely,
     we can get multi-entity clusters, in which case all but one must
     only be reached from within the cluster.  This happens for
     something like:

     template<typename T>
     auto Foo (const T &arg) -> TPL<decltype (arg)>;

     The instantiation of TPL will be in the specialization table, and
     refer to Foo via arg.  But we can only get to that specialization
     from Foo's declaration, so we only need to treat Foo as mergable
     (We'll do structural comparison of TPL<decltype (arg)>).

     Finding the single cluster entry dep is very tricky and
     expensive.  Let's just not do that.  It's harmless in this case
     anyway. */

However, as this PR shows it's not harmless; it's somewhat just luck that the
(consistent) sort happens to work for the existing cases in the testsuite
(modules/late-ret*).

Finding the single cluster entry dep in sort_cluster is probably already too
late, since if this is the only cluster in the SCC we don't have any
information about which deps reference us.  And we probably want to be sorted
correctly even before we hit sort_cluster so that we ensure we never hit this
ICE from within the sort_cluster find_dependencies walk.

I have a couple of hacky solutions for this specific issue, including guessing
that any declaration first found via a merge-key walk is not the entry dep, but
I'm not convinced I have a general solution yet that won't be very expensive.

Reply via email to