On 10/18/25 5:52 PM, Patrick Palka wrote:
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.

Hmm, right, we want the visibility of g to be affected by the template arguments to A in the argument type, but determine_visibility for g relies on the CLASSTYPE_VISIBILITY of that dependent A specialization, and that change breaks that dependency.

To avoid that I guess we'd need to recurse into the template arguments.

I'll try just ignoring local variables instead and see how that goes.

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?

That still works out to ic<true> at instantiation time, which should not have constrained visibility.

I think this further illustrates the distinction between a dependent expression in the template signature vs. one in a use of a template in another context.

+      else if (!TREE_PUBLIC (t))
        tpvis = VISIBILITY_ANON;
        else
        tpvis = DECL_VISIBILITY (t);

Reply via email to