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