aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2007-10-26 15:54:10 -0400
committerJason Merrill <jason@gcc.gnu.org>2007-10-26 15:54:10 -0400
commit91a77d68e72ba6e7597884fc10afd07a9700bb5a (patch)
treeb60524076cf0b62e70c6417f3dd6b09eb6c76300 /gcc
parent4552f5a2c81d09f3d1af9aad2203e95162c2e3a8 (diff)
downloadgcc-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/ChangeLog8
-rw-r--r--gcc/cp/cp-tree.h1
-rw-r--r--gcc/cp/pt.c77
-rw-r--r--gcc/testsuite/g++.dg/template/error33.C11
-rw-r--r--gcc/testsuite/g++.old-deja/g++.pt/crash11.C2
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" }
{
};