On 7/21/26 3:41 PM, Patrick Palka wrote:
Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look OK for trunk and backports?
OK.
-- >8 -- This is just the pack version of PR c++/105848, in which our non-dependent call pruning may cause us to not mark an otherwise unused function pointer template argument as used. PR c++/126280 gcc/cp/ChangeLog: * pt.cc (mark_template_arguments_used): Split out loop into ... (mark_template_arguments_used_1): ... here. Recurse into argument packs. gcc/testsuite/ChangeLog: * g++.dg/template/fn-ptr6.C: New test. --- gcc/cp/pt.cc | 11 +++++++++++ gcc/testsuite/g++.dg/template/fn-ptr6.C | 26 +++++++++++++++++++++++++ 2 files changed, 37 insertions(+) create mode 100644 gcc/testsuite/g++.dg/template/fn-ptr6.C diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc index 1290db45e182..ced68a238650 100644 --- a/gcc/cp/pt.cc +++ b/gcc/cp/pt.cc @@ -224,6 +224,7 @@ static bool uses_outer_template_parms (tree); static tree alias_ctad_tweaks (tree, tree); static tree inherited_ctad_tweaks (tree, tree, tsubst_flags_t); static tree deduction_guides_for (tree, bool&, tsubst_flags_t); +static void mark_template_arguments_used_1 (tree);/* Make the current scope suitable for access checking when we areprocessing T. T can be FUNCTION_DECL for instantiated function @@ -23738,6 +23739,14 @@ mark_template_arguments_used (tree tmpl, tree args) /* We already marked outer arguments when specializing the context. */ args = INNERMOST_TEMPLATE_ARGS (args);+ mark_template_arguments_used_1 (args);+} + +/* Main recursive part of the above. */ + +static void +mark_template_arguments_used_1 (tree args) +{ for (tree arg : tree_vec_range (args)) { /* A (pointer/reference to) function or variable NTTP argument. */ @@ -23778,6 +23787,8 @@ mark_template_arguments_used (tree tmpl, tree args) cp_walk_tree_without_duplicates (&DECL_INITIAL (arg), mark_used_r, nullptr); } + else if (TREE_CODE (arg) == NONTYPE_ARGUMENT_PACK) + mark_template_arguments_used_1 (ARGUMENT_PACK_ARGS (arg)); } }diff --git a/gcc/testsuite/g++.dg/template/fn-ptr6.C b/gcc/testsuite/g++.dg/template/fn-ptr6.Cnew file mode 100644 index 000000000000..fa111c6d9429 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/fn-ptr6.C @@ -0,0 +1,26 @@ +// PR c++/126280 +// A version of fn-ptr3a.C where the template parameter is a pack. +// { dg-do compile { target c++11 } } + +template<class T> +void f(T) { T::fail; } // { dg-error "fail" } + +template<void (*...P)(int)> +struct A { + // P not called +}; + +template<void (&...P)(char)> +void wrap() { + // P not called +} + +template<int> +void g() { + A<f> a; // { dg-message "required from" } + wrap<f>(); // { dg-message "required from" } +} + +int main() { + g<0>(); +}
