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
This commit is contained in:
parent
4552f5a2c8
commit
91a77d68e7
@ -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
|
||||
|
@ -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);
|
||||
|
77
gcc/cp/pt.c
77
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;
|
||||
|
11
gcc/testsuite/g++.dg/template/error33.C
Normal file
11
gcc/testsuite/g++.dg/template/error33.C
Normal file
@ -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;
|
@ -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" }
|
||||
{
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user