diff options
author | Jason Merrill <jason@redhat.com> | 2007-10-26 15:54:10 -0400 |
---|---|---|
committer | Jason Merrill <jason@gcc.gnu.org> | 2007-10-26 15:54:10 -0400 |
commit | 91a77d68e72ba6e7597884fc10afd07a9700bb5a (patch) | |
tree | b60524076cf0b62e70c6417f3dd6b09eb6c76300 /gcc | |
parent | 4552f5a2c81d09f3d1af9aad2203e95162c2e3a8 (diff) | |
download | gcc-91a77d68e72ba6e7597884fc10afd07a9700bb5a.zip gcc-91a77d68e72ba6e7597884fc10afd07a9700bb5a.tar.gz gcc-91a77d68e72ba6e7597884fc10afd07a9700bb5a.tar.bz2 |
re PR c++/24791 (ICE on invalid instantiation of template's static member)
PR c++/24791
* pt.c (get_template_info): New fn.
(template_class_depth): Use it.
(push_template_decl_real): Check that the template args of the
definition match the args of the previous declaration.
From-SVN: r129660
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/cp/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/cp/cp-tree.h | 1 | ||||
-rw-r--r-- | gcc/cp/pt.c | 77 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/template/error33.C | 11 | ||||
-rw-r--r-- | gcc/testsuite/g++.old-deja/g++.pt/crash11.C | 2 |
5 files changed, 65 insertions, 34 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 99a2bc5..0ef16bf 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,11 @@ +2007-10-26 Jason Merrill <jason@redhat.com> + + PR c++/24791 + * pt.c (get_template_info): New fn. + (template_class_depth): Use it. + (push_template_decl_real): Check that the template args of the + definition match the args of the previous declaration. + 2007-10-26 Paolo Carlini <pcarlini@suse.de> PR c++/31988 diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index bb02692..f57f2f9 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -4437,6 +4437,7 @@ extern bool uses_parameter_packs (tree); extern bool template_parameter_pack_p (const_tree); extern tree make_pack_expansion (tree); extern bool check_for_bare_parameter_packs (tree); +extern tree get_template_info (tree); extern int template_class_depth (tree); extern int is_specialization_of (tree, tree); extern bool is_specialization_of_friend (tree, tree); diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index a54e90d..9193f48 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -263,6 +263,25 @@ finish_member_template_decl (tree decl) return error_mark_node; } +/* Return the template info node corresponding to T, whatever T is. */ + +tree +get_template_info (tree t) +{ + tree tinfo = NULL_TREE; + + if (DECL_P (t) && DECL_LANG_SPECIFIC (t)) + tinfo = DECL_TEMPLATE_INFO (t); + + if (!tinfo && TREE_CODE (t) == TYPE_DECL) + t = TREE_TYPE (t); + + if (TAGGED_TYPE_P (t)) + tinfo = TYPE_TEMPLATE_INFO (t); + + return tinfo; +} + /* Returns the template nesting level of the indicated class TYPE. For example, in: @@ -291,20 +310,11 @@ template_class_depth (tree type) type = (TREE_CODE (type) == FUNCTION_DECL) ? CP_DECL_CONTEXT (type) : TYPE_CONTEXT (type)) { - if (TREE_CODE (type) != FUNCTION_DECL) - { - if (CLASSTYPE_TEMPLATE_INFO (type) - && PRIMARY_TEMPLATE_P (CLASSTYPE_TI_TEMPLATE (type)) - && uses_template_parms (CLASSTYPE_TI_ARGS (type))) - ++depth; - } - else - { - if (DECL_TEMPLATE_INFO (type) - && PRIMARY_TEMPLATE_P (DECL_TI_TEMPLATE (type)) - && uses_template_parms (DECL_TI_ARGS (type))) - ++depth; - } + tree tinfo = get_template_info (type); + + if (tinfo && PRIMARY_TEMPLATE_P (TI_TEMPLATE (tinfo)) + && uses_template_parms (INNERMOST_TEMPLATE_ARGS (TI_ARGS (tinfo)))) + ++depth; } return depth; @@ -3866,27 +3876,15 @@ push_template_decl_real (tree decl, bool is_friend) { tree a, t, current, parms; int i; + tree tinfo = get_template_info (decl); - if (TREE_CODE (decl) == TYPE_DECL) - { - if ((IS_AGGR_TYPE_CODE (TREE_CODE (TREE_TYPE (decl))) - || TREE_CODE (TREE_TYPE (decl)) == ENUMERAL_TYPE) - && TYPE_TEMPLATE_INFO (TREE_TYPE (decl)) - && TYPE_TI_TEMPLATE (TREE_TYPE (decl))) - tmpl = TYPE_TI_TEMPLATE (TREE_TYPE (decl)); - else - { - error ("%qD does not declare a template type", decl); - return decl; - } - } - else if (!DECL_LANG_SPECIFIC (decl) || !DECL_TEMPLATE_INFO (decl)) + if (!tinfo) { error ("template definition of non-template %q#D", decl); return decl; } - else - tmpl = DECL_TI_TEMPLATE (decl); + + tmpl = TI_TEMPLATE (tinfo); if (DECL_FUNCTION_TEMPLATE_P (tmpl) && DECL_TEMPLATE_INFO (decl) && DECL_TI_ARGS (decl) @@ -3946,9 +3944,6 @@ push_template_decl_real (tree decl, bool is_friend) return error_mark_node; } - /* Perhaps we should also check that the parms are used in the - appropriate qualifying scopes in the declarator? */ - if (current == decl) current = ctx; else @@ -3956,6 +3951,22 @@ push_template_decl_real (tree decl, bool is_friend) ? TYPE_CONTEXT (current) : DECL_CONTEXT (current)); } + + /* Check that the parms are used in the appropriate qualifying scopes + in the declarator. */ + if (!comp_template_args + (TI_ARGS (tinfo), + TI_ARGS (get_template_info (DECL_TEMPLATE_RESULT (tmpl))))) + { + error ("\ +template arguments to %qD do not match original template %qD", + decl, DECL_TEMPLATE_RESULT (tmpl)); + if (!uses_template_parms (TI_ARGS (tinfo))) + inform ("use template<> for an explicit specialization"); + /* Avoid crash in import_export_decl. */ + DECL_INTERFACE_KNOWN (decl) = 1; + return error_mark_node; + } } DECL_TEMPLATE_RESULT (tmpl) = decl; diff --git a/gcc/testsuite/g++.dg/template/error33.C b/gcc/testsuite/g++.dg/template/error33.C new file mode 100644 index 0000000..e1ac822 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/error33.C @@ -0,0 +1,11 @@ +// PR c++/24791 + +template<int> struct A +{ + static int i; + A() { ++i; } +}; + +template<int> int A<0>::i(0); // { dg-error "template" } + +A<0> a; diff --git a/gcc/testsuite/g++.old-deja/g++.pt/crash11.C b/gcc/testsuite/g++.old-deja/g++.pt/crash11.C index be83f5a..5f372d3 100644 --- a/gcc/testsuite/g++.old-deja/g++.pt/crash11.C +++ b/gcc/testsuite/g++.old-deja/g++.pt/crash11.C @@ -8,6 +8,6 @@ class A }; -template <class j> class A::A_impl // { dg-error "does not declare a template" } +template <class j> class A::A_impl // { dg-error "non-template" } { }; |