When passing a function template as the argument to a function NTTP inside a template, we resolve it to the right specialization ahead of time via resolve_address_of_overloaded_function, though the call to mark_used within defers odr-using it until instantiation time (as usual). But at instantiation time we end up never calling mark_used on the specialization.
This patch fixes this by adding a call to mark_used in convert_nontype_argument_function. PR c++/53164 gcc/cp/ChangeLog: * pt.c (convert_nontype_argument_function): Call mark_used. gcc/testsuite/ChangeLog: * g++.dg/template/non-dependent16.C: New test. --- gcc/cp/pt.c | 3 +++ gcc/testsuite/g++.dg/template/non-dependent16.C | 16 ++++++++++++++++ 2 files changed, 19 insertions(+) create mode 100644 gcc/testsuite/g++.dg/template/non-dependent16.C diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index f950f4a21b7..5e819c9598c 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -6668,6 +6668,9 @@ convert_nontype_argument_function (tree type, tree expr, return NULL_TREE; } + if (!mark_used (fn_no_ptr, complain) && !(complain & tf_error)) + return NULL_TREE; + linkage = decl_linkage (fn_no_ptr); if (cxx_dialect >= cxx11 ? linkage == lk_none : linkage != lk_external) { diff --git a/gcc/testsuite/g++.dg/template/non-dependent16.C b/gcc/testsuite/g++.dg/template/non-dependent16.C new file mode 100644 index 00000000000..b7dca8f6752 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/non-dependent16.C @@ -0,0 +1,16 @@ +// PR c++/53164 + +template<class T> +void f(T) { + T::fail; // { dg-error "not a member" } +} + +template<void(int)> +struct A { }; + +template<int> +void g() { + A<f> a; +} + +template void g<0>(); -- 2.33.0.610.gcefe983a32