On Wed, 27 Nov 2024, Patrick Palka wrote: > Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look OK > for trunk/14/13?
Ping. It occurred to me that another way to fix this PR might be to tweak the overload set pruning (for non-dependent calls) to un-specialize the selected function template specialization if it turned out to be dependent: diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc index efa748c7dc8..08d05209f44 100644 --- a/gcc/cp/semantics.cc +++ b/gcc/cp/semantics.cc @@ -3311,6 +3311,13 @@ finish_call_expr (tree fn, vec<tree, va_gc> **args, bool disallow_virtual, /* Our original callee wasn't wrapped in an ADDR_EXPR, so strip this ADDR_EXPR added by build_over_call. */ sel_fn = TREE_OPERAND (sel_fn, 0); + if (TREE_CODE (sel_fn) == FUNCTION_DECL + && type_dependent_expression_p (sel_fn) + && PRIMARY_TEMPLATE_P (DECL_TI_TEMPLATE (sel_fn))) + { + sel_fn = ovl_make (DECL_TI_TEMPLATE (sel_fn)); + sel_fn = lookup_template_function (fns, ...); + } orig_fn = sel_fn; } But IMHO this should be impossible in the first place -- if an unresolved overload set is deemed non-dependent then any specialization selected by overload resolution should be deemed non-dependent as well. Or conversely if overload resolution yielded a dependent specialization then the unresolved overload set should be considered dependent. > > -- >8 -- > > Here we end up ICEing at instantiation time for the call to > f<local_static> ultimately because we wrongly consider the call to be > non-dependent, and so we specialize f ahead of time and then get > confused when fully substituting this specialization. > > The call is dependent due to [temp.dep.temp]/3 and we miss that because > function template-id arguments aren't coerced until overload resolution, > and so the local static template argument lacks an implicit cast to > reference type that value_dependent_expression_p looks for before > considering dependence of the address. Other kinds of template-ids aren't > affected since they're coerced ahead of time. > > So when considering dependence of a function template-id, we need to > conservatively consider dependence of the address of each argument (if > applicable). > > PR c++/117792 > > gcc/cp/ChangeLog: > > * pt.cc (type_dependent_expression_p): Consider the dependence > of the address of each template argument of a function > template-id. > > gcc/testsuite/ChangeLog: > > * g++.dg/cpp1z/nontype7.C: New test. > --- > gcc/cp/pt.cc | 10 ++++++++-- > gcc/testsuite/g++.dg/cpp1z/nontype7.C | 22 ++++++++++++++++++++++ > 2 files changed, 30 insertions(+), 2 deletions(-) > create mode 100644 gcc/testsuite/g++.dg/cpp1z/nontype7.C > > diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc > index 564e368ff43..2f2ec39b083 100644 > --- a/gcc/cp/pt.cc > +++ b/gcc/cp/pt.cc > @@ -28864,9 +28864,15 @@ type_dependent_expression_p (tree expression) > > if (TREE_CODE (expression) == TEMPLATE_ID_EXPR) > { > - if (any_dependent_template_arguments_p > - (TREE_OPERAND (expression, 1))) > + tree args = TREE_OPERAND (expression, 1); > + if (any_dependent_template_arguments_p (args)) > return true; > + /* Arguments of a function template-id aren't necessarily coerced > + yet so we must conservatively assume that the address (and not > + just value) of the argument matters as per [temp.dep.temp]/3. */ > + for (tree arg : tree_vec_range (args)) > + if (has_value_dependent_address (arg)) > + return true; > expression = TREE_OPERAND (expression, 0); > if (identifier_p (expression)) > return true; > diff --git a/gcc/testsuite/g++.dg/cpp1z/nontype7.C > b/gcc/testsuite/g++.dg/cpp1z/nontype7.C > new file mode 100644 > index 00000000000..b03c643c987 > --- /dev/null > +++ b/gcc/testsuite/g++.dg/cpp1z/nontype7.C > @@ -0,0 +1,22 @@ > +// PR c++/117792 > +// { dg-do compile { target c++17 } } > + > +template<const int& N, class T> > +void f(T) { } > + > +template<int, class T> > +void f(...) = delete; > + > +template<const int& N> int v; > + > +template<const int& N> struct A { static const int value = 0; }; > + > +template<class T> > +void g() { > + static const int local_static = 0; > + auto x = v<local_static>; // OK > + auto y = A<local_static>::value; // OK > + f<local_static>(0); // ICE > +} > + > +template void g<int>(); > -- > 2.47.1.313.gcc01bad4a9 > >