Jason Merrill <ja...@redhat.com> writes: > On 11/28/2011 11:54 AM, Dodji Seketeli wrote: >> @@ -3028,10 +3028,12 @@ find_parameter_packs_r (tree*tp, int *walk_subtrees, >> void* data) >> >> case BOUND_TEMPLATE_TEMPLATE_PARM: >> /* Check the template itself. */ >> - cp_walk_tree (&TREE_TYPE (TYPE_TI_TEMPLATE (t)), >> + cp_walk_tree (&TREE_TYPE (TI_TEMPLATE >> + (TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO (t))), >> &find_parameter_packs_r, ppd, ppd->visited); >> /* Check the template arguments. */ >> - cp_walk_tree (&TYPE_TI_ARGS (t),&find_parameter_packs_r, ppd, >> + cp_walk_tree (&TI_ARGS (TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO (t)), >> + &find_parameter_packs_r, ppd, >> ppd->visited); >> *walk_subtrees = 0; >> return NULL_TREE; > > Instead of this change, I think we should handle typedefs/aliases at > the top of the function. We shouldn't need to look into the > underlying type for packs.
Thus, I have bootstrapped and tested the below on x86_64-unknown-linux-gnu against trunk. I had to make TYPE_ALIAS_P more robust so that it doesn't crash on TEMPLATE_TEMPLATE_PARMs which TYPE_NAME are TEMPLATE_DECL nodes, unlike the other types that use TYPE_DECL nodes that. gcc/cp/ PR c++/51289 * cp-tree.h (TYPE_TEMPLATE_INFO): Rewrite this accessor macro to better support aliased types. (TYPE_ALIAS_P): Don't crash on TYPE_NAME nodes that are not TYPE_DECL. * pt.c (find_parameter_packs_r): Handle typedef variant types. gcc/testsuite/ PR c++/51289 * g++.dg/cpp0x/alias-decl-17.C: New test. --- gcc/cp/cp-tree.h | 28 ++++++++++++++++++---------- gcc/cp/pt.c | 14 ++++++++++++++ gcc/testsuite/g++.dg/cpp0x/alias-decl-17.C | 13 +++++++++++++ 3 files changed, 45 insertions(+), 10 deletions(-) create mode 100644 gcc/testsuite/g++.dg/cpp0x/alias-decl-17.C diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 3f4f408..b821928 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -2553,6 +2553,7 @@ extern void decl_shadowed_for_var_insert (tree, tree); #define TYPE_ALIAS_P(NODE) \ (TYPE_P (NODE) \ && TYPE_NAME (NODE) \ + && TREE_CODE (TYPE_NAME (NODE)) == TYPE_DECL \ && TYPE_DECL_ALIAS_P (TYPE_NAME (NODE))) /* For a class type: if this structure has many fields, we'll sort them @@ -2605,17 +2606,24 @@ extern void decl_shadowed_for_var_insert (tree, tree); (LANG_TYPE_CLASS_CHECK (BOUND_TEMPLATE_TEMPLATE_PARM_TYPE_CHECK (NODE)) \ ->template_info) -/* Template information for an ENUMERAL_, RECORD_, or UNION_TYPE. */ +/* Template information for an ENUMERAL_, RECORD_, UNION_TYPE, or + BOUND_TEMPLATE_TEMPLATE_PARM type. Note that if NODE is a + specialization of an alias template, this accessor returns the + template info for the alias template, not the one (if any) for the + template of the underlying type. */ #define TYPE_TEMPLATE_INFO(NODE) \ - (TREE_CODE (NODE) == ENUMERAL_TYPE \ - ? ENUM_TEMPLATE_INFO (NODE) : \ - (TREE_CODE (NODE) == BOUND_TEMPLATE_TEMPLATE_PARM \ - ? TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO (NODE) : \ - ((CLASS_TYPE_P (NODE) && !TYPE_ALIAS_P (NODE)) \ - ? CLASSTYPE_TEMPLATE_INFO (NODE) \ - : ((TYPE_NAME (NODE) && DECL_LANG_SPECIFIC (TYPE_NAME (NODE))) \ - ? (DECL_TEMPLATE_INFO (TYPE_NAME (NODE))) \ - : NULL_TREE)))) + (TYPE_ALIAS_P (NODE) \ + ? ((TYPE_NAME (NODE) && DECL_LANG_SPECIFIC (TYPE_NAME (NODE))) \ + ? DECL_TEMPLATE_INFO (TYPE_NAME (NODE)) \ + : NULL_TREE) \ + : ((TREE_CODE (NODE) == ENUMERAL_TYPE) \ + ? ENUM_TEMPLATE_INFO (NODE) \ + : ((TREE_CODE (NODE) == BOUND_TEMPLATE_TEMPLATE_PARM) \ + ? TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO (NODE) \ + : (CLASS_TYPE_P (NODE) \ + ? CLASSTYPE_TEMPLATE_INFO (NODE) \ + : NULL_TREE)))) + /* Set the template information for an ENUMERAL_, RECORD_, or UNION_TYPE to VAL. */ diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 4725080..5bc6f23 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -2976,6 +2976,20 @@ find_parameter_packs_r (tree *tp, int *walk_subtrees, void* data) (struct find_parameter_pack_data*)data; bool parameter_pack_p = false; + /* Handle type aliases/typedefs. */ + if (TYPE_P (t) && typedef_variant_p (t)) + { + if (TYPE_TEMPLATE_INFO (t)) + cp_walk_tree (&TYPE_TI_ARGS (t), + &find_parameter_packs_r, + ppd, ppd->visited); + cp_walk_tree (&DECL_ORIGINAL_TYPE (TYPE_NAME (t)), + &find_parameter_packs_r, + ppd, ppd->visited); + *walk_subtrees = 0; + return NULL_TREE; + } + /* Identify whether this is a parameter pack or not. */ switch (TREE_CODE (t)) { diff --git a/gcc/testsuite/g++.dg/cpp0x/alias-decl-17.C b/gcc/testsuite/g++.dg/cpp0x/alias-decl-17.C new file mode 100644 index 0000000..a7b2d37 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/alias-decl-17.C @@ -0,0 +1,13 @@ +// Origin PR c++/51289 +// { dg-options "-std=c++11" } + +template<typename a, template <typename, typename> class b> +struct foo { + template <typename t> + using type = b<a, t>; + template <typename t> + b<a, t> funca() {} + + template <typename t> + type<t> funcb() {} +}; -- 1.7.6.4 -- Dodji