On 5/14/25 6:26 AM, Nathaniel Shead wrote:
On Tue, May 13, 2025 at 12:40:30PM -0400, Jason Merrill wrote:
On 5/9/25 11:48 AM, Nathaniel Shead wrote:
Bootstrapped and regtested on x86_64-pc-linux-gnu, OK for trunk/15?

One slight concern I have is why we end up in 'maybe_thunk_body' to
start with: the imported constructor isn't DECL_ONE_ONLY (as its
external) and so 'can_alias_cdtor' returns false.

That does seem like a problem; can_alias_cdtor shouldn't change due to
explicit instantiation.

The change in
write_function_def (which I believe is necessary regardless) hides this
because we never actually emit the function definitions, but I worry
that this might somehow affect LTO, though I haven't been able to
construct a testcase which fails.  To avoid the potential of that we
could do something like this to mark such functions as DECL_ONE_ONLY
just in case; thoughts?

diff --git a/gcc/cp/module.cc b/gcc/cp/module.cc
index e7782627a49..c96e81aceef 100644
--- a/gcc/cp/module.cc
+++ b/gcc/cp/module.cc
@@ -16738,9 +16738,15 @@ module_state::read_cluster (unsigned snum)
         /* Make sure we emit explicit instantiations.
            FIXME do we want to do this in expand_or_defer_fn instead?  */
-      if (DECL_EXPLICIT_INSTANTIATION (decl)
-          && !DECL_EXTERNAL (decl))
-        setup_explicit_instantiation_definition_linkage (decl);
+      if (DECL_EXPLICIT_INSTANTIATION (decl))
+        {
+          if (DECL_DECLARED_INLINE_P (decl)
+              && TREE_PUBLIC (decl)
+              && DECL_MAYBE_IN_CHARGE_CDTOR_P (decl))
+            maybe_make_one_only (decl);

This seems fragile, we shouldn't need to reproduce this specific behavior
here.

Agreed.

How is this case different from an extern template in a single TU?

It looks like the difference is that in a single TU, an extern template
is never marked as DECL_WEAK, and so in can_alias_cdtor we check
DECL_INTERFACE_KNOWN && !DECL_ONE_ONLY instead.  In the modules case,
the explicit instantiation definition is marked as DECL_WEAK by
make_decl_one_only (in setup_explicit_instantiation_definition_linkage),
which we inherit.

So perhaps we should additionally clear DECL_WEAK on export for explicit
instantiations?  Or maybe DECL_WEAK should only be set when we import
the definition, as with DECL_NOT_REALLY_EXTERN.  I'm not sure if any
other of the visibility flags will also need special treatment (maybe
DECL_COMDAT?).

I think it makes sense for us to end up on import with the same result as calling mark_decl_instantiated (true) in the first place, whatever that is. Perhaps with an undo_explicit_instantiation_definition_linkage function.

In particular, I think we want to avoid DECL_WEAK on external references so we aren't emitting weak references.

Jason

Reply via email to