find_parameter_packs_r doesn't look through typedefs, which is normally correct, but that means we need to handle their declarations specially.
Tested x86_64-pc-linux-gnu, applying to trunk. gcc/cp/ChangeLog 2020-03-14 Jason Merrill <ja...@redhat.com> PR c++/92909 * pt.c (find_parameter_packs_r): [DECL_EXPR]: Walk DECL_ORIGINAL_TYPE of a typedef. --- gcc/cp/pt.c | 16 ++++++++++++---- .../g++.dg/cpp0x/lambda/lambda-variadic10.C | 12 ++++++++++++ 2 files changed, 24 insertions(+), 4 deletions(-) create mode 100644 gcc/testsuite/g++.dg/cpp0x/lambda/lambda-variadic10.C diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 0f3c2ad8fec..bd2f9be82ea 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -3916,10 +3916,18 @@ find_parameter_packs_r (tree *tp, int *walk_subtrees, void* data) return NULL_TREE; case DECL_EXPR: - /* Ignore the declaration of a capture proxy for a parameter pack. */ - if (is_capture_proxy (DECL_EXPR_DECL (t))) - *walk_subtrees = 0; - return NULL_TREE; + { + tree decl = DECL_EXPR_DECL (t); + /* Ignore the declaration of a capture proxy for a parameter pack. */ + if (is_capture_proxy (decl)) + *walk_subtrees = 0; + if (is_typedef_decl (decl)) + /* Since we stop at typedefs above, we need to look through them at + the point of the DECL_EXPR. */ + cp_walk_tree (&DECL_ORIGINAL_TYPE (decl), + &find_parameter_packs_r, ppd, ppd->visited); + return NULL_TREE; + } case TEMPLATE_DECL: if (!DECL_TEMPLATE_TEMPLATE_PARM_P (t)) diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-variadic10.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-variadic10.C new file mode 100644 index 00000000000..052283e6caa --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-variadic10.C @@ -0,0 +1,12 @@ +// PR c++/92909 +// { dg-do compile { target c++11 } } + +template <class ... Ts> +void foo() +{ + [] + { + using T = Ts; + }(); // { dg-error "not expanded" } +} +template void foo<>(); base-commit: 53b28abf8e4ba37e47d3bb05476e0a80ae761567 -- 2.18.1