On Fri, 17 Oct 2025, Patrick Palka wrote:

> On Fri, 17 Oct 2025, Jason Merrill wrote:
> 
> > On 10/16/25 2:58 PM, Nathaniel Shead wrote:
> > > I'm not 100% sure this is the correct approach, or whether I've picked
> > > the right sense of "dependent" to check here; any thoughts?
> > 
> > I think it makes sense to return early in expr_visibility if the argument is
> > value-dependent.
> 
> I believe that'll break g++.dg/abi/no-linkage-expr1.C, the
> value-dependent ((P)0, N) needs to be walked so that the anon type P
> within forces specializations of f and g to have internal linkage.
> 
> This seems similar to PR110323 / r14-9596-g081f8937cb82da except for
> local variables instead of constexpr variables. So maybe the
> decl_constant_var_p code path should be used for local vars too?

.. the decl_constant_var_p code path added by r14-9596, to be precise.

Like with constexpr variables, a (non-constexpr) local variable
within a template argument shouldn't affect linkage because presumably
it's only used for its value.

> 
> > > Bootstrapped and regtested on x86_64-pc-linux-gnu, OK for trunk?
> > > 
> > > -- >8 --
> > > 
> > > When finding the minimal visibility of a template, any reference to a
> > > dependent local variable will cause the instantiation to be marked as
> > > internal linkage.  However, when processing the template decl we don't
> > > yet know whether that should actually be the case, as a given
> > > instantiation may not require referencing the local decl in its
> > > mangling.  So this patch bails on dependent declarations.
> > > 
> > >   PR c++/122253
> > > 
> > > gcc/cp/ChangeLog:
> > > 
> > >   * decl2.cc (min_vis_expr_r): Don't mark as VISIBILITY_ANON for a
> > >   !TREE_PUBLIC dependent decl.
> > > 
> > > gcc/testsuite/ChangeLog:
> > > 
> > >   * g++.dg/modules/internal-16.C: New test.
> > > 
> > > Signed-off-by: Nathaniel Shead <[email protected]>
> > > ---
> > >   gcc/cp/decl2.cc                            |  5 ++++-
> > >   gcc/testsuite/g++.dg/modules/internal-16.C | 23 ++++++++++++++++++++++
> > >   2 files changed, 27 insertions(+), 1 deletion(-)
> > >   create mode 100644 gcc/testsuite/g++.dg/modules/internal-16.C
> > > 
> > > diff --git a/gcc/cp/decl2.cc b/gcc/cp/decl2.cc
> > > index 0073f83a10c..572037acd38 100644
> > > --- a/gcc/cp/decl2.cc
> > > +++ b/gcc/cp/decl2.cc
> > > @@ -2885,7 +2885,10 @@ min_vis_expr_r (tree *tp, int */*walk_subtrees*/,
> > > void *data)
> > >             break;
> > >           }
> > >       addressable:
> > > -      if (! TREE_PUBLIC (t))
> > > +      if (!TREE_PUBLIC (t)
> > > +   /* We don't really know whether a use of a dependent decl will
> > > +      actually appear in our mangling.  */
> > > +   && !dependent_type_p (TREE_TYPE (t)))
> > >           tpvis = VISIBILITY_ANON;
> > >         else
> > >           tpvis = DECL_VISIBILITY (t);
> > > diff --git a/gcc/testsuite/g++.dg/modules/internal-16.C
> > > b/gcc/testsuite/g++.dg/modules/internal-16.C
> > > new file mode 100644
> > > index 00000000000..a891082cc1b
> > > --- /dev/null
> > > +++ b/gcc/testsuite/g++.dg/modules/internal-16.C
> > > @@ -0,0 +1,23 @@
> > > +// PR c++/122253
> > > +// { dg-additional-options "-fmodules -Wtemplate-names-tu-local" }
> > > +
> > > +export module M;
> > > +
> > > +template <int> struct ic {};
> > > +struct S { constexpr operator int() const { return 42; } };
> > > +
> > > +template <typename T> inline void a(T) {
> > > +  T s;
> > > +  ic<s>{};
> > > +}
> > > +
> > > +template <typename T> inline auto b(T x) {
> > > +  return [&](auto y) {
> > > +    return [=](auto z) {
> > > +      return ic<(int)x + (int)y + (int)z>{};
> > > +    };
> > > +  };
> > > +}
> > > +
> > > +template void a(S);
> > > +ic<42 * 3> x = b(S{})(S{})(S{});
> > 
> > 
> 

Reply via email to