Commit ae52af05 by Jason Merrill Committed by Jason Merrill

parser.c (cp_parser_check_for_invalid_template_id): tag_type parm.

	* parser.c (cp_parser_check_for_invalid_template_id): tag_type parm.
	(cp_parser_simple_type_specifier, cp_parser_class_head): Adjust.
	(cp_parser_elaborated_type_specifier): Adjust.
	* decl.c (duplicate_decls): Return error_mark_node on template
	mismatch.

From-SVN: r189025
parent b298aa9b
2012-06-27 Jason Merrill <jason@redhat.com> 2012-06-27 Jason Merrill <jason@redhat.com>
* parser.c (cp_parser_check_for_invalid_template_id): tag_type parm.
(cp_parser_simple_type_specifier, cp_parser_class_head): Adjust.
(cp_parser_elaborated_type_specifier): Adjust.
* decl.c (duplicate_decls): Return error_mark_node on template
mismatch.
PR c++/53563 PR c++/53563
* parser.c (cp_parser_template_id): Add tag_type parm. * parser.c (cp_parser_template_id): Add tag_type parm.
(cp_parser_template_name): Likewise. (cp_parser_template_name): Likewise.
......
...@@ -1463,6 +1463,7 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend) ...@@ -1463,6 +1463,7 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend)
{ {
error ("declaration of template %q#D", newdecl); error ("declaration of template %q#D", newdecl);
error ("conflicts with previous declaration %q+#D", olddecl); error ("conflicts with previous declaration %q+#D", olddecl);
return error_mark_node;
} }
else if (TREE_CODE (DECL_TEMPLATE_RESULT (olddecl)) == FUNCTION_DECL else if (TREE_CODE (DECL_TEMPLATE_RESULT (olddecl)) == FUNCTION_DECL
&& TREE_CODE (DECL_TEMPLATE_RESULT (newdecl)) == FUNCTION_DECL && TREE_CODE (DECL_TEMPLATE_RESULT (newdecl)) == FUNCTION_DECL
......
...@@ -2278,7 +2278,7 @@ static bool cp_parser_check_type_definition ...@@ -2278,7 +2278,7 @@ static bool cp_parser_check_type_definition
static void cp_parser_check_for_definition_in_return_type static void cp_parser_check_for_definition_in_return_type
(cp_declarator *, tree, location_t type_location); (cp_declarator *, tree, location_t type_location);
static void cp_parser_check_for_invalid_template_id static void cp_parser_check_for_invalid_template_id
(cp_parser *, tree, location_t location); (cp_parser *, tree, enum tag_types, location_t location);
static bool cp_parser_non_integral_constant_expression static bool cp_parser_non_integral_constant_expression
(cp_parser *, non_integral_constant); (cp_parser *, non_integral_constant);
static void cp_parser_diagnose_invalid_type_name static void cp_parser_diagnose_invalid_type_name
...@@ -2551,7 +2551,9 @@ cp_parser_check_for_definition_in_return_type (cp_declarator *declarator, ...@@ -2551,7 +2551,9 @@ cp_parser_check_for_definition_in_return_type (cp_declarator *declarator,
static void static void
cp_parser_check_for_invalid_template_id (cp_parser* parser, cp_parser_check_for_invalid_template_id (cp_parser* parser,
tree type, location_t location) tree type,
enum tag_types tag_type,
location_t location)
{ {
cp_token_position start = 0; cp_token_position start = 0;
...@@ -2560,7 +2562,12 @@ cp_parser_check_for_invalid_template_id (cp_parser* parser, ...@@ -2560,7 +2562,12 @@ cp_parser_check_for_invalid_template_id (cp_parser* parser,
if (TYPE_P (type)) if (TYPE_P (type))
error_at (location, "%qT is not a template", type); error_at (location, "%qT is not a template", type);
else if (TREE_CODE (type) == IDENTIFIER_NODE) else if (TREE_CODE (type) == IDENTIFIER_NODE)
error_at (location, "%qE is not a template", type); {
if (tag_type != none_type)
error_at (location, "%qE is not a class template", type);
else
error_at (location, "%qE is not a template", type);
}
else else
error_at (location, "invalid template-id"); error_at (location, "invalid template-id");
/* Remember the location of the invalid "<". */ /* Remember the location of the invalid "<". */
...@@ -13668,7 +13675,8 @@ cp_parser_simple_type_specifier (cp_parser* parser, ...@@ -13668,7 +13675,8 @@ cp_parser_simple_type_specifier (cp_parser* parser,
/* There is no valid C++ program where a non-template type is /* There is no valid C++ program where a non-template type is
followed by a "<". That usually indicates that the user thought followed by a "<". That usually indicates that the user thought
that the type was a template. */ that the type was a template. */
cp_parser_check_for_invalid_template_id (parser, type, token->location); cp_parser_check_for_invalid_template_id (parser, type, none_type,
token->location);
return TYPE_NAME (type); return TYPE_NAME (type);
} }
...@@ -13770,6 +13778,7 @@ cp_parser_simple_type_specifier (cp_parser* parser, ...@@ -13770,6 +13778,7 @@ cp_parser_simple_type_specifier (cp_parser* parser,
followed by a "<". That usually indicates that the user followed by a "<". That usually indicates that the user
thought that the type was a template. */ thought that the type was a template. */
cp_parser_check_for_invalid_template_id (parser, TREE_TYPE (type), cp_parser_check_for_invalid_template_id (parser, TREE_TYPE (type),
none_type,
token->location); token->location);
} }
...@@ -14273,7 +14282,8 @@ cp_parser_elaborated_type_specifier (cp_parser* parser, ...@@ -14273,7 +14282,8 @@ cp_parser_elaborated_type_specifier (cp_parser* parser,
/* A "<" cannot follow an elaborated type specifier. If that /* A "<" cannot follow an elaborated type specifier. If that
happens, the user was probably trying to form a template-id. */ happens, the user was probably trying to form a template-id. */
cp_parser_check_for_invalid_template_id (parser, type, token->location); cp_parser_check_for_invalid_template_id (parser, type, tag_type,
token->location);
return type; return type;
} }
...@@ -18429,6 +18439,7 @@ cp_parser_class_head (cp_parser* parser, ...@@ -18429,6 +18439,7 @@ cp_parser_class_head (cp_parser* parser,
if (id) if (id)
{ {
cp_parser_check_for_invalid_template_id (parser, id, cp_parser_check_for_invalid_template_id (parser, id,
class_key,
type_start_token->location); type_start_token->location);
} }
virt_specifiers = cp_parser_virt_specifier_seq_opt (parser); virt_specifiers = cp_parser_virt_specifier_seq_opt (parser);
......
2012-06-27 Jason Merrill <jason@redhat.com> 2012-06-27 Jason Merrill <jason@redhat.com>
* g++.dg/cpp0x/override2.C: Adjust.
* g++.dg/template/error5.C: Adjust.
* g++.dg/parse/crash28.C: Adjust.
PR c++/53563 PR c++/53563
* g++.dg/parse/template27.C: New. * g++.dg/parse/template27.C: New.
* g++.dg/template/crash74.C: Adjust expected output. * g++.dg/template/crash74.C: Adjust expected output.
......
...@@ -18,7 +18,7 @@ template <class T> struct B4 final {}; ...@@ -18,7 +18,7 @@ template <class T> struct B4 final {};
template <class T> struct B5 final {}; template <class T> struct B5 final {};
struct undeclared<int> final { }; // { dg-error "not a template" } struct undeclared<int> final { }; // { dg-error "not a class template" }
struct D5 : B3<D5> {}; struct D5 : B3<D5> {};
......
...@@ -5,10 +5,10 @@ ...@@ -5,10 +5,10 @@
// Origin:Andrew Pinski <pinskia@gcc.gnu.org> // Origin:Andrew Pinski <pinskia@gcc.gnu.org>
// Volker Reichelt <reichelt@gcc.gnu.org> // Volker Reichelt <reichelt@gcc.gnu.org>
template <class _Tp> class insert_iterator<slist<_Tp> > {}; // { dg-error "not a template|not declared in this scope|expected unqualified-id|extra" } template <class _Tp> class insert_iterator<slist<_Tp> > {}; // { dg-error "not a class template|not declared in this scope|expected unqualified-id|extra" }
template <class _Value> class insert_iterator<int > { // { dg-error "template" } template <class _Value> class insert_iterator<int > { // { dg-error "template" }
hash_set<_Value>; hash_set<_Value>;
}; };
template<int> struct A<X<> > {}; // { dg-error "not a template|not declared in this scope|expected unqualified-id|extra" } template<int> struct A<X<> > {}; // { dg-error "not a class template|not declared in this scope|expected unqualified-id|extra" }
struct A {}; struct A {};
template <typename T> template <typename T>
struct X<T*> { // { dg-error "not a template" } struct X<T*> { // { dg-error "not a class template" }
typedef int Y; typedef int Y;
}; };
extern struct Z<int> s; // { dg-error "not a template" } extern struct Z<int> s; // { dg-error "not a class template" }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment