On Thu, Jan 09, 2025 at 05:41:07PM -0500, Patrick Palka wrote:
> On Fri, 10 Jan 2025, Nathaniel Shead wrote:
> 
> > Bootstrapped and regtested on x86_64-pc-linux-gnu, OK for trunk/14?
> 
> Nice approach, thanks for fixing this!
> 
> > 
> > -- >8 --
> > 
> > In the linked testcase, an ICE occurs because when reading the
> > (duplicate) function definition for _M_do_parse from module Y, the local
> > type definitions have already been streamed from module X and setup as
> > regular backreferences, rather than being found with find_duplicate,
> > causing issues with managing DECL_CHAIN.
> > 
> > It is tempting to just skip setting up the DECL_CHAIN for this case.
> > However, for the future it would be best to ensure that the block vars
> > for the duplicate definition are accurate, so that we could implement
> > ODR checking on function definitions at some point.
> > 
> > So to solve this, this patch creates a copy of the streamed-in local
> > type and chains that; it will be discarded along with the rest of the
> > duplicate function after we've finished processing.
> > 
> > A couple of suggested implementations from the discussion on the PR that
> > don't work:
> > 
> > - Replacing the `DECL_CHAIN` assertion with `(*chain && *chain != decl)`
> >   doesn't handle the case where type definitions are followed by regular
> >   local variables, since those won't have been imported as separate
> >   backreferences and so the chains will diverge.
> > 
> > - Correcting the purviewness of GMF template instantiations to force Y
> >   to emit copies of the local types rather than backreferences into X is
> >   insufficient, as it's still possible that the local types got streamed
> >   in a separate cluster to the function definition, and so will be again
> >   referred to via regular backreferences when importing.
> > 
> > - Likewise, preventing the emission of function definitions where an
> >   import has already provided that same definition also is insufficient,
> >   for much the same reason.
> > 
> >     PR c++/114630
> > 
> > gcc/cp/ChangeLog:
> > 
> >     * module.cc (trees_in::core_vals) <BLOCK>: Chain a new node if
> >     DECL_CHAIN already is set.
> > 
> > gcc/testsuite/ChangeLog:
> > 
> >     * g++.dg/modules/pr114630.h: New test.
> >     * g++.dg/modules/pr114630_a.C: New test.
> >     * g++.dg/modules/pr114630_b.C: New test.
> >     * g++.dg/modules/pr114630_c.C: New test.
> > 
> > Signed-off-by: Nathaniel Shead <nathanielosh...@gmail.com>
> > ---
> >  gcc/cp/module.cc                          | 14 +++++++++++++-
> >  gcc/testsuite/g++.dg/modules/pr114630.h   | 11 +++++++++++
> >  gcc/testsuite/g++.dg/modules/pr114630_a.C |  7 +++++++
> >  gcc/testsuite/g++.dg/modules/pr114630_b.C |  8 ++++++++
> >  gcc/testsuite/g++.dg/modules/pr114630_c.C |  4 ++++
> >  5 files changed, 43 insertions(+), 1 deletion(-)
> >  create mode 100644 gcc/testsuite/g++.dg/modules/pr114630.h
> >  create mode 100644 gcc/testsuite/g++.dg/modules/pr114630_a.C
> >  create mode 100644 gcc/testsuite/g++.dg/modules/pr114630_b.C
> >  create mode 100644 gcc/testsuite/g++.dg/modules/pr114630_c.C
> > 
> > diff --git a/gcc/cp/module.cc b/gcc/cp/module.cc
> > index 5350e6c4bad..ff2683de73e 100644
> > --- a/gcc/cp/module.cc
> > +++ b/gcc/cp/module.cc
> > @@ -6928,11 +6928,23 @@ trees_in::core_vals (tree t)
> >            body) anyway.  */
> >         decl = maybe_duplicate (decl);
> >  
> > -       if (!DECL_P (decl) || DECL_CHAIN (decl))
> > +       if (!DECL_P (decl))
> >           {
> >             set_overrun ();
> >             break;
> >           }
> > +
> > +       /* If DECL_CHAIN is already set then this was a backreference to a
> > +          local type or enumerator from a previous read (PR c++/114630).
> > +          Let's copy the node so we can keep building the chain for ODR
> > +          checking later.  */
> > +       if (DECL_CHAIN (decl))
> > +         {
> > +           gcc_checking_assert (TREE_CODE (decl) == TYPE_DECL
> > +                                && find_duplicate (DECL_CONTEXT (decl)));
> > +           decl = copy_node (decl);
> 
> Shall we use copy_decl here instead so that any DECL_LANG_SPECIFIC node
> is copied as well?  IIUC we usually don't share DECL_LANG_SPECIFIC
> between decls.
> 

Happy to use copy_decl instead; I'll retest tonight and push tomorrow if
there's no issues.  Thanks!

> > +         }
> > +
> >         *chain = decl;
> >         chain = &DECL_CHAIN (decl);
> >       }
> > diff --git a/gcc/testsuite/g++.dg/modules/pr114630.h 
> > b/gcc/testsuite/g++.dg/modules/pr114630.h
> > new file mode 100644
> > index 00000000000..8730007f59f
> > --- /dev/null
> > +++ b/gcc/testsuite/g++.dg/modules/pr114630.h
> > @@ -0,0 +1,11 @@
> > +template <typename _CharT>
> > +void _M_do_parse() {
> > +  struct A {};
> > +  struct B {};
> > +  int x;
> > +}
> > +
> > +template <typename> struct formatter;
> > +template <> struct formatter<int> {
> > +  void parse() { _M_do_parse<int>(); }
> > +};
> > diff --git a/gcc/testsuite/g++.dg/modules/pr114630_a.C 
> > b/gcc/testsuite/g++.dg/modules/pr114630_a.C
> > new file mode 100644
> > index 00000000000..ecfd7ca0b28
> > --- /dev/null
> > +++ b/gcc/testsuite/g++.dg/modules/pr114630_a.C
> > @@ -0,0 +1,7 @@
> > +// { dg-additional-options "-fmodules" }
> > +// { dg-module-cmi X }
> > +
> > +module;
> > +#include "pr114630.h"
> > +export module X;
> > +formatter<int> a;
> > diff --git a/gcc/testsuite/g++.dg/modules/pr114630_b.C 
> > b/gcc/testsuite/g++.dg/modules/pr114630_b.C
> > new file mode 100644
> > index 00000000000..52fe04e2ce0
> > --- /dev/null
> > +++ b/gcc/testsuite/g++.dg/modules/pr114630_b.C
> > @@ -0,0 +1,8 @@
> > +// { dg-additional-options "-fmodules" }
> > +// { dg-module-cmi Y }
> > +
> > +module;
> > +#include "pr114630.h"
> > +export module Y;
> > +import X;
> > +formatter<int> b;
> > diff --git a/gcc/testsuite/g++.dg/modules/pr114630_c.C 
> > b/gcc/testsuite/g++.dg/modules/pr114630_c.C
> > new file mode 100644
> > index 00000000000..54a21f08057
> > --- /dev/null
> > +++ b/gcc/testsuite/g++.dg/modules/pr114630_c.C
> > @@ -0,0 +1,4 @@
> > +// { dg-additional-options "-fmodules" }
> > +
> > +#include "pr114630.h"
> > +import Y;
> > -- 
> > 2.47.0
> > 
> > 
> 

Reply via email to