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?

> > 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