]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
c++: find A pack from B in <typename...A,Class<A>...B> [PR118265]
authorA J Ryan Solutions Ltd <gcc.gnu.org@ajryansolutions.co.uk>
Sun, 2 Feb 2025 22:26:32 +0000 (22:26 +0000)
committerJason Merrill <jason@redhat.com>
Mon, 3 Feb 2025 23:49:35 +0000 (18:49 -0500)
For non-type parameter packs when unifying the arguments in
unify_pack_expansion it iterates over the associated packs of a param so
that when it recursively unifies the param with the arguments it knows
which targs have been populated with parameter pack arguments that it can
then collect up. This change adds a tree walk so that in the example above
it reaches ...A and adds it to the associated packs for ...B and therefore
knows it will have been set in targs in unify_pack_expansion and processes
it as per other pack arguments.

PR c++/118265

gcc/cp/ChangeLog:

* pt.cc (find_parameter_packs_r) <case TEMPLATE_PARM_INDEX>:
Walk into the type of a parameter pack.

Signed-off-by: Adam J Ryan <gcc.gnu.org@ajryansolutions.co.uk>
gcc/cp/pt.cc
gcc/testsuite/g++.dg/cpp1z/variadic-nontype1.C [new file with mode: 0644]

index 77583dd6bb52de8d35e4e4874e3471490715d546..39232b5e67fd8fb3d792a0b43ed2d84730d27927 100644 (file)
@@ -4010,6 +4010,11 @@ find_parameter_packs_r (tree *tp, int *walk_subtrees, void* data)
                    &find_parameter_packs_r, ppd, ppd->visited);
       return NULL_TREE;
 
+    case TEMPLATE_PARM_INDEX:
+      if (parameter_pack_p)
+       WALK_SUBTREE (TREE_TYPE (t));
+      return NULL_TREE;
+
     case DECL_EXPR:
       {
        tree decl = DECL_EXPR_DECL (t);
diff --git a/gcc/testsuite/g++.dg/cpp1z/variadic-nontype1.C b/gcc/testsuite/g++.dg/cpp1z/variadic-nontype1.C
new file mode 100644 (file)
index 0000000..ad2af62
--- /dev/null
@@ -0,0 +1,18 @@
+// { dg-do compile { target c++17 } }
+struct Class1
+{
+    void apply_bool(bool){}
+    void apply_char(char){}
+};
+
+template<auto...Fn> struct Class2;
+template<typename...P, void(Class1::*...Fn)(P)> struct Class2<Fn...>
+{
+    void apply(){}
+};
+
+int main()
+{
+    Class2<&Class1::apply_bool, &Class1::apply_char> class2;
+    class2.apply ();
+}