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{}); > > > > >
