]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
c++: function NTTP argument in pack considered unused [PR126280]
authorPatrick Palka <ppalka@redhat.com>
Sat, 25 Jul 2026 20:12:19 +0000 (16:12 -0400)
committerPatrick Palka <ppalka@redhat.com>
Sat, 25 Jul 2026 20:12:19 +0000 (16:12 -0400)
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 <jason@redhat.com>
gcc/cp/pt.cc
gcc/testsuite/g++.dg/template/fn-ptr6.C [new file with mode: 0644]

index b18fa5c02cfe78a001d3f5731f759c6af0d2f322..6a081b838e0643756c6d7f23938b869fd939106c 100644 (file)
@@ -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 (file)
index 0000000..fa111c6
--- /dev/null
@@ -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>();
+}