Jason Merrill <ja...@redhat.com> writes: > I guess let's check DECL_ORIGINAL_TYPE instead of TREE_TYPE for alias > templates.
Like the below that I am currently bootstrapping? From: Dodji Seketeli <do...@redhat.com> Date: Sat, 26 Nov 2011 11:50:43 +0100 Subject: [PATCH] PR c++/51289 - ICE with alias template for bound template template parm 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. (push_template_decl_real): Check for bare parameter packs in the underlying type of an alias template. gcc/PR51289/gcc/testsuite/ PR c++/51289 * g++.dg/cpp0x/alias-decl-17.C: New test. --- gcc/cp/cp-tree.h | 28 ++++++++++++++++++---------- gcc/cp/pt.c | 16 +++++++++++++++- gcc/testsuite/g++.dg/cpp0x/alias-decl-17.C | 21 +++++++++++++++++++++ 3 files changed, 54 insertions(+), 11 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..7ae0e18 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -2976,6 +2976,17 @@ 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); + *walk_subtrees = 0; + return NULL_TREE; + } + /* Identify whether this is a parameter pack or not. */ switch (TREE_CODE (t)) { @@ -4905,7 +4916,10 @@ push_template_decl_real (tree decl, bool is_friend) if (check_for_bare_parameter_packs (TYPE_RAISES_EXCEPTIONS (type))) TYPE_RAISES_EXCEPTIONS (type) = NULL_TREE; } - else if (check_for_bare_parameter_packs (TREE_TYPE (decl))) + else if (check_for_bare_parameter_packs ((TREE_CODE (decl) == TYPE_DECL + && TYPE_DECL_ALIAS_P (decl)) + ? DECL_ORIGINAL_TYPE (decl) + : TREE_TYPE (decl))) { TREE_TYPE (decl) = error_mark_node; return error_mark_node; 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..41b1c95 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/alias-decl-17.C @@ -0,0 +1,21 @@ +// 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() {} +}; + +// This is an additional test, to emit an error message when using +// unexpanded parameter packs in an alias declaration. +template <class ... T> +struct S {}; + +template<class ... T> +using A = S<T>; // { dg-error "parameter packs not expanded" } -- 1.7.6.4 -- Dodji