https://gcc.gnu.org/g:26d3424ca5d9f47d7e0b6fcaf0fae48435a73442

commit r15-7339-g26d3424ca5d9f47d7e0b6fcaf0fae48435a73442
Author: A J Ryan Solutions Ltd <gcc.gnu....@ajryansolutions.co.uk>
Date:   Sun Feb 2 22:26:32 2025 +0000

    c++: find A pack from B in <typename...A,Class<A>...B> [PR118265]
    
    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....@ajryansolutions.co.uk>

Diff:
---
 gcc/cp/pt.cc                                   |  5 +++++
 gcc/testsuite/g++.dg/cpp1z/variadic-nontype1.C | 18 ++++++++++++++++++
 2 files changed, 23 insertions(+)

diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc
index 77583dd6bb52..39232b5e67fd 100644
--- a/gcc/cp/pt.cc
+++ b/gcc/cp/pt.cc
@@ -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
index 000000000000..ad2af623b139
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1z/variadic-nontype1.C
@@ -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 ();
+}

Reply via email to