Re: [PATCH] c++: lambda in pack expansion [PR115378]
On 6/7/24 10:44, Patrick Palka wrote: Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look OK for trunk/14? OK. -- >8 -- Here find_parameter_packs_r is incorrectly treating the 'auto' return type of a lambda as a parameter pack due to Concepts-TS specific logic added in r6-4517, leading to confusion later when expanding the pattern. Since we intend on removing Concepts TS support soon anyway, this patch fixes this by restricting the problematic logic with flag_concepts_ts. Doing so revealed that add_capture was relying on this logic to set TEMPLATE_TYPE_PARAMETER_PACK for the 'auto' type of an init-capture pack expansion, which we now need to do explicitly. PR c++/115378 gcc/cp/ChangeLog: * lambda.cc (lambda_capture_field_type): Set TEMPLATE_TYPE_PARAMETER_PACK on the auto type of an init-capture pack expansion. * pt.cc (find_parameter_packs_r) : Restrict TEMPLATE_TYPE_PARAMETER_PACK promotion with flag_concepts_ts. gcc/testsuite/ChangeLog: * g++.dg/cpp1y/decltype-auto-103497.C: Adjust expected diagnostic. * g++.dg/template/pr95672.C: Likewise. * g++.dg/cpp2a/lambda-targ5.C: New test. --- gcc/cp/lambda.cc | 3 ++- gcc/cp/pt.cc | 2 +- gcc/testsuite/g++.dg/cpp1y/decltype-auto-103497.C | 2 +- gcc/testsuite/g++.dg/cpp2a/lambda-targ5.C | 15 +++ gcc/testsuite/g++.dg/template/pr95672.C | 2 +- 5 files changed, 20 insertions(+), 4 deletions(-) create mode 100644 gcc/testsuite/g++.dg/cpp2a/lambda-targ5.C diff --git a/gcc/cp/lambda.cc b/gcc/cp/lambda.cc index 630cc4eade1..0770417810e 100644 --- a/gcc/cp/lambda.cc +++ b/gcc/cp/lambda.cc @@ -223,7 +223,8 @@ lambda_capture_field_type (tree expr, bool explicit_init_p, outermost CV qualifiers of EXPR. */ type = build_reference_type (type); if (uses_parameter_packs (expr)) - /* Stick with 'auto' even if the type could be deduced. */; + /* Stick with 'auto' even if the type could be deduced. */ + TEMPLATE_TYPE_PARAMETER_PACK (auto_node) = true; else type = do_auto_deduction (type, expr, auto_node); } diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc index dfce1b3c359..6ee27d6fa16 100644 --- a/gcc/cp/pt.cc +++ b/gcc/cp/pt.cc @@ -3940,7 +3940,7 @@ find_parameter_packs_r (tree *tp, int *walk_subtrees, void* data) parameter pack (14.6.3), or the type-specifier-seq of a type-id that is a pack expansion, the invented template parameter is a template parameter pack. */ - if (ppd->type_pack_expansion_p && is_auto (t) + if (flag_concepts_ts && ppd->type_pack_expansion_p && is_auto (t) && TEMPLATE_TYPE_LEVEL (t) != 0) TEMPLATE_TYPE_PARAMETER_PACK (t) = true; if (TEMPLATE_TYPE_PARAMETER_PACK (t)) diff --git a/gcc/testsuite/g++.dg/cpp1y/decltype-auto-103497.C b/gcc/testsuite/g++.dg/cpp1y/decltype-auto-103497.C index cedd661710c..4162361d14f 100644 --- a/gcc/testsuite/g++.dg/cpp1y/decltype-auto-103497.C +++ b/gcc/testsuite/g++.dg/cpp1y/decltype-auto-103497.C @@ -1,7 +1,7 @@ // PR c++/103497 // { dg-do compile { target c++14 } } -void foo(decltype(auto)... args); // { dg-error "cannot declare a parameter with .decltype.auto.." } +void foo(decltype(auto)... args); // { dg-error "contains no parameter packs" } int main() { foo(); diff --git a/gcc/testsuite/g++.dg/cpp2a/lambda-targ5.C b/gcc/testsuite/g++.dg/cpp2a/lambda-targ5.C new file mode 100644 index 000..efd4bb45d58 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/lambda-targ5.C @@ -0,0 +1,15 @@ +// PR c++/115378 +// { dg-do compile { target c++20 } } + +struct tt {}; + +template +constexpr auto __counter = 1; + +template +using _as_base = tt; + +template +struct env : _as_base>... {}; + +env t; diff --git a/gcc/testsuite/g++.dg/template/pr95672.C b/gcc/testsuite/g++.dg/template/pr95672.C index c752b4a2c08..d97b8db2e97 100644 --- a/gcc/testsuite/g++.dg/template/pr95672.C +++ b/gcc/testsuite/g++.dg/template/pr95672.C @@ -1,3 +1,3 @@ // PR c++/95672 // { dg-do compile { target c++14 } } -struct g_class : decltype (auto) ... { }; // { dg-error "invalid use of pack expansion" } +struct g_class : decltype (auto) ... { }; // { dg-error "contains no parameter packs" }
[PATCH] c++: lambda in pack expansion [PR115378]
Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look OK for trunk/14? -- >8 -- Here find_parameter_packs_r is incorrectly treating the 'auto' return type of a lambda as a parameter pack due to Concepts-TS specific logic added in r6-4517, leading to confusion later when expanding the pattern. Since we intend on removing Concepts TS support soon anyway, this patch fixes this by restricting the problematic logic with flag_concepts_ts. Doing so revealed that add_capture was relying on this logic to set TEMPLATE_TYPE_PARAMETER_PACK for the 'auto' type of an init-capture pack expansion, which we now need to do explicitly. PR c++/115378 gcc/cp/ChangeLog: * lambda.cc (lambda_capture_field_type): Set TEMPLATE_TYPE_PARAMETER_PACK on the auto type of an init-capture pack expansion. * pt.cc (find_parameter_packs_r) : Restrict TEMPLATE_TYPE_PARAMETER_PACK promotion with flag_concepts_ts. gcc/testsuite/ChangeLog: * g++.dg/cpp1y/decltype-auto-103497.C: Adjust expected diagnostic. * g++.dg/template/pr95672.C: Likewise. * g++.dg/cpp2a/lambda-targ5.C: New test. --- gcc/cp/lambda.cc | 3 ++- gcc/cp/pt.cc | 2 +- gcc/testsuite/g++.dg/cpp1y/decltype-auto-103497.C | 2 +- gcc/testsuite/g++.dg/cpp2a/lambda-targ5.C | 15 +++ gcc/testsuite/g++.dg/template/pr95672.C | 2 +- 5 files changed, 20 insertions(+), 4 deletions(-) create mode 100644 gcc/testsuite/g++.dg/cpp2a/lambda-targ5.C diff --git a/gcc/cp/lambda.cc b/gcc/cp/lambda.cc index 630cc4eade1..0770417810e 100644 --- a/gcc/cp/lambda.cc +++ b/gcc/cp/lambda.cc @@ -223,7 +223,8 @@ lambda_capture_field_type (tree expr, bool explicit_init_p, outermost CV qualifiers of EXPR. */ type = build_reference_type (type); if (uses_parameter_packs (expr)) - /* Stick with 'auto' even if the type could be deduced. */; + /* Stick with 'auto' even if the type could be deduced. */ + TEMPLATE_TYPE_PARAMETER_PACK (auto_node) = true; else type = do_auto_deduction (type, expr, auto_node); } diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc index dfce1b3c359..6ee27d6fa16 100644 --- a/gcc/cp/pt.cc +++ b/gcc/cp/pt.cc @@ -3940,7 +3940,7 @@ find_parameter_packs_r (tree *tp, int *walk_subtrees, void* data) parameter pack (14.6.3), or the type-specifier-seq of a type-id that is a pack expansion, the invented template parameter is a template parameter pack. */ - if (ppd->type_pack_expansion_p && is_auto (t) + if (flag_concepts_ts && ppd->type_pack_expansion_p && is_auto (t) && TEMPLATE_TYPE_LEVEL (t) != 0) TEMPLATE_TYPE_PARAMETER_PACK (t) = true; if (TEMPLATE_TYPE_PARAMETER_PACK (t)) diff --git a/gcc/testsuite/g++.dg/cpp1y/decltype-auto-103497.C b/gcc/testsuite/g++.dg/cpp1y/decltype-auto-103497.C index cedd661710c..4162361d14f 100644 --- a/gcc/testsuite/g++.dg/cpp1y/decltype-auto-103497.C +++ b/gcc/testsuite/g++.dg/cpp1y/decltype-auto-103497.C @@ -1,7 +1,7 @@ // PR c++/103497 // { dg-do compile { target c++14 } } -void foo(decltype(auto)... args); // { dg-error "cannot declare a parameter with .decltype.auto.." } +void foo(decltype(auto)... args); // { dg-error "contains no parameter packs" } int main() { foo(); diff --git a/gcc/testsuite/g++.dg/cpp2a/lambda-targ5.C b/gcc/testsuite/g++.dg/cpp2a/lambda-targ5.C new file mode 100644 index 000..efd4bb45d58 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/lambda-targ5.C @@ -0,0 +1,15 @@ +// PR c++/115378 +// { dg-do compile { target c++20 } } + +struct tt {}; + +template +constexpr auto __counter = 1; + +template +using _as_base = tt; + +template +struct env : _as_base>... {}; + +env t; diff --git a/gcc/testsuite/g++.dg/template/pr95672.C b/gcc/testsuite/g++.dg/template/pr95672.C index c752b4a2c08..d97b8db2e97 100644 --- a/gcc/testsuite/g++.dg/template/pr95672.C +++ b/gcc/testsuite/g++.dg/template/pr95672.C @@ -1,3 +1,3 @@ // PR c++/95672 // { dg-do compile { target c++14 } } -struct g_class : decltype (auto) ... { }; // { dg-error "invalid use of pack expansion" } +struct g_class : decltype (auto) ... { }; // { dg-error "contains no parameter packs" } -- 2.45.2.409.g7b0defb391