[Dodji Seketeli] Re: [PATCH] PR c++/51289 - ICE with alias template for bound template
Friendly pinging this patch. ---BeginMessage--- Dodji Seketeli do...@redhat.com writes: 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? Finally this is what passed bootstrap and testing on x86_64-unknown-linux-gnu against trunk. 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 types aliases. (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| 19 ++- gcc/testsuite/g++.dg/cpp0x/alias-decl-17.C | 21 + 3 files changed, 57 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..ee3a3ab 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) + TYPE_NAME (t) + TREE_CODE (TYPE_NAME (t)) == TYPE_DECL + TYPE_DECL_ALIAS_P (TYPE_NAME (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 +4919,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
Re: [PATCH] PR c++/51289 - ICE with alias template for bound template
Dodji Seketeli do...@redhat.com writes: 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? Finally this is what passed bootstrap and testing on x86_64-unknown-linux-gnu against trunk. 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 types aliases. (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| 19 ++- gcc/testsuite/g++.dg/cpp0x/alias-decl-17.C | 21 + 3 files changed, 57 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..ee3a3ab 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) + TYPE_NAME (t) + TREE_CODE (TYPE_NAME (t)) == TYPE_DECL + TYPE_DECL_ALIAS_P (TYPE_NAME (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 +4919,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
Re: [PATCH] PR c++/51289 - ICE with alias template for bound template
Jason Merrill ja...@redhat.com writes: On 11/29/2011 10:41 AM, Dodji Seketeli wrote: + cp_walk_tree (DECL_ORIGINAL_TYPE (TYPE_NAME (t)), +find_parameter_packs_r, +ppd, ppd-visited); I still don't think we want to walk the underlying type, since it isn't part of the syntactic form of the type in this context and therefore can't have relevant packs. Here is an example of what I had in mind for keeping the walking of the underlying type there: template class ... T struct S {}; templateclass ... T using A = ST;//#1 -- I think we should error here. When we are in #1, in the process of building the template info for A, push_template_decl_real_1 calls check_for_bare_parameter_packs, which then call the code you are referring to. If we don't walk the underlying type there, we miss spotting the use the of the bare parameter pack T. Or am I miss-considering something? FWIW, below is an updated patch with that example included. Bootstrapped and tested on x86_64-unknown-linux-gnu against trunk. 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/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| 14 ++ gcc/testsuite/g++.dg/cpp0x/alias-decl-17.C | 21 + 3 files changed, 53 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
Re: [PATCH] PR c++/51289 - ICE with alias template for bound template
On 11/30/2011 06:32 AM, Dodji Seketeli wrote: Here is an example of what I had in mind for keeping the walking of the underlying type there: templateclass ... T struct S {}; templateclass ... T using A = ST;//#1-- I think we should error here. We certainly should; we do need to walk the pattern at the point of definition. I meant that when we see a use of a typedef or alias template we don't need to walk the underlying type. When we are in #1, in the process of building the template info for A, push_template_decl_real_1 calls check_for_bare_parameter_packs, which then call the code you are referring to. If we don't walk the underlying type there, we miss spotting the use the of the bare parameter pack T. Or am I miss-considering something? I guess let's check DECL_ORIGINAL_TYPE instead of TREE_TYPE for alias templates. Jason
Re: [PATCH] PR c++/51289 - ICE with alias template for bound template
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)
Re: [PATCH] PR c++/51289 - ICE with alias template for bound template
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
Re: [PATCH] PR c++/51289 - ICE with alias template for bound template
On 11/29/2011 10:41 AM, Dodji Seketeli wrote: + cp_walk_tree (DECL_ORIGINAL_TYPE (TYPE_NAME (t)), + find_parameter_packs_r, + ppd, ppd-visited); I still don't think we want to walk the underlying type, since it isn't part of the syntactic form of the type in this context and therefore can't have relevant packs. Jason
Re: [PATCH] PR c++/51289 - ICE with alias template for bound template
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. Jason