[gcc r17-2706] c++: function NTTP argument in pack considered unused [PR126280]

Patrick Palka via Gcc-cvs <[email protected]>
Newsgroups gmane.comp.gcc.cvs
Message-ID <[email protected]>
https://gcc.gnu.org/g:d47f48643b3db4e207b0cc3382f614aa76c9c2c5

commit r17-2706-gd47f48643b3db4e207b0cc3382f614aa76c9c2c5
Author: Patrick Palka <[email protected]>
Date:   Sat Jul 25 16:12:19 2026 -0400

    c++: function NTTP argument in pack considered unused [PR126280]
    
    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 within a pack 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.
    
    Reviewed-by: Jason Merrill <[email protected]>

Diff:
---
 gcc/cp/pt.cc                            | 11 +++++++++++
 gcc/testsuite/g++.dg/template/fn-ptr6.C | 26 ++++++++++++++++++++++++++
 2 files changed, 37 insertions(+)

diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc
index b18fa5c02cfe..6a081b838e06 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 are
    processing T.  T can be FUNCTION_DECL for instantiated function
@@ -23739,6 +23740,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.  */
@@ -23779,6 +23788,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.C
new 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>();
+}
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.