[gcc r16-9409] 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:9fad76fa86f5a1464fbe52f926750a389727910d

commit r16-9409-g9fad76fa86f5a1464fbe52f926750a389727910d
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]>
    (cherry picked from commit d47f48643b3db4e207b0cc3382f614aa76c9c2c5)

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 f055cc4e276b..9d3a972e3002 100644
--- a/gcc/cp/pt.cc
+++ b/gcc/cp/pt.cc
@@ -223,6 +223,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
@@ -23538,6 +23539,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.  */
@@ -23578,6 +23587,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.