On Sun, 19 Oct 2025, Nathaniel Shead wrote:

> On Sat, Oct 18, 2025 at 06:38:57PM +1100, Nathaniel Shead wrote:
> > On Sat, Oct 18, 2025 at 10:35:15AM +0300, Jason Merrill wrote:
> > > On 10/17/25 7:15 PM, Patrick Palka wrote:
> > > > 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.
> > > 
> > > Ah, indeed, the distinction is also between dependent expressions in the
> > > template signature vs those in a template argument.
> > > 
> > > Maybe it would be better to check for dependent template arguments in
> > > constrain_visibility_for_template?
> > > 
> > 
> > That had actually been my first attempt, to check
> > 'dependent_template_arg_p' in 'constrain_visibility_for_template', but
> > that also caused abi/no-linkage-expr1.C to fail, which is why I
> > went with the approach I did.
> > 
> > I'll try just ignoring local variables instead and see how that goes.
> > 
> 
> And here's that patch: Bootstrapped and regtested on
> x86_64-pc-linux-gnu, OK for trunk/15?
> 
> -- >8 --
> 
> Subject: [PATCH] c++: Don't constrain visibility using local variables 
> [PR122253]
> 
> 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 local variables.
> 
>       PR c++/122253
> 
> gcc/cp/ChangeLog:
> 
>       * decl2.cc (min_vis_expr_r): Don't mark as VISIBILITY_ANON for a
>       local variable.
> 
> gcc/testsuite/ChangeLog:
> 
>       * g++.dg/modules/internal-16.C: New test.
> 
> Signed-off-by: Nathaniel Shead <[email protected]>
> Reviewed-by: Patrick Palka <[email protected]>
> Reviewed-by: Jason Merrill <[email protected]>
> ---
>  gcc/cp/decl2.cc                            |  7 ++++++-
>  gcc/testsuite/g++.dg/modules/internal-16.C | 23 ++++++++++++++++++++++
>  2 files changed, 29 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..5efab46ef91 100644
> --- a/gcc/cp/decl2.cc
> +++ b/gcc/cp/decl2.cc
> @@ -2885,7 +2885,12 @@ min_vis_expr_r (tree *tp, int */*walk_subtrees*/, void 
> *data)
>         break;
>       }
>      addressable:
> -      if (! TREE_PUBLIC (t))
> +      if (local_variable_p (t))
> +     /* Likewise, local variables being used as a template argument are
> +        presumably only used for their value, so shouldn't constrain its
> +        visibility.  */
> +     tpvis = type_visibility (TREE_TYPE (t));

This local_variable_p check needs to be moved up before the
'addressable' label so that for a local_variable_p decl whose address
_is_ needed (in a contrived way e.g. ic<&s != nullptr>), we still
constrain the containing thing's visibility, I think?

> +      else if (!TREE_PUBLIC (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{});
> -- 
> 2.51.0
> 
> 

Reply via email to