On 12/23/25 8:31 PM, Nathaniel Shead wrote:
On Thu, Dec 18, 2025 at 11:03:12AM +0700, Jason Merrill wrote:
On 12/16/25 6:34 PM, Nathaniel Shead wrote:
Here's attempt two at this patch, with a testcase for the linker issue
I'd inadvertantly caused with my previous attempt.

Bootstrapped and regtested on x86_64-pc-linux-gnu, OK for trunk?

-- >8 --

Modules allow temploid friends to no longer be implicitly inline, as
functions defined in a class body will not be implicitly inline if
attached to a named module.

This requires us to clean up linkage handling a little bit, mostly by
replacing usages of 'DECL_TEMPLATE_INSTANTIATION' with
'DECL_TEMPLOID_INSTANTIATION' when determining if an entity has vague
linkage.

This caused the friend88.C testcase to miscompile however, as 'foo' was
incorrectly having 'DECL_FRIEND_PSEUDO_TEMPLATE_INSTANTIATION' getting
set because it was keeping its tinfo.

This is because 'non_templated_friend_p' was returning 'false', since
the function didn't have a primary template.  But that's expected I
think here, so fixed by also returning true for friend declarations
pushed into namespace scope, which still allows dependent nested friends
to be considered templated.

Will that wrongly return true for a friend namespace-scope template? The
test should check that case.

It does not; in cases like

   template <typename T> friend void namespace_scope();

this is a primary template and so primary is non-null anyway, and
'primary != tmpl' returns false.  I'm not sure how to test this though,
as the test I've been using here only works because the affected
functions should not be comdat, but for a function template it should be
comdat anyway.  And this would not be a pseudo template instantiation
regardless, as it's actually a template.

It seems like a bug that TPARMS_PRIMARY_TEMPLATE would ever be null.

Assuming this is about 'template <class T> friend A<T>::f()', this
appears to be deliberate from this hunk in push_template_decl added
in r0-76180-gc9cbfca6 (PR c++/27714):

   bool is_primary = false;
   if (is_friend && ctx
       && uses_template_parms_level (ctx, current_template_depth))
     /* A friend template that specifies a class context, i.e.
          template <typename T> friend void A<T>::f();
        is not primary.  */
     ;

And indeed removing this causes redeclaration errors.  I'm not sure how
(or indeed, if it would be sensible) to change this.

Makes sense, the patch is OK.

Jason

Reply via email to