Commit 7f9faf5e by Lee Millward Committed by Lee Millward

re PR c++/29022 (ICE using operator int in invalid class hierarchy)

	PR c++/29022
	* parser.c (cp_parser_class_head): Move processing
	of any base classes to...
	(cp_parser_class_specifier) ...here. Take an extra
	tree* parameter for any base classes. Only process
	them if the opening brace was found.

	* g++.dg/inherit/virtual2.C: New test.
	* g++.dg/inherit/virtual3.C: Likewise.
	* g++.old-deja/g++.bugs/900121_05.C: Adjust error markers.
	* g++.dg/inherit/error2.C: Likewise.
	* g++.dg/template/instantiate1.C: Likewise.

From-SVN: r119318
parent 8b65a354
2006-11-29 Lee Millward <lee.millward@codesourcery.com>
PR c++/29022
* parser.c (cp_parser_class_head): Move processing
of any base classes to...
(cp_parser_class_specifier) ...here. Take an extra
tree* parameter for any base classes. Only process
them if the opening brace was found.
2006-11-28 Jakub Jelinek <jakub@redhat.com> 2006-11-28 Jakub Jelinek <jakub@redhat.com>
PR c++/29735 PR c++/29735
......
...@@ -1639,7 +1639,7 @@ static tree cp_parser_class_name ...@@ -1639,7 +1639,7 @@ static tree cp_parser_class_name
static tree cp_parser_class_specifier static tree cp_parser_class_specifier
(cp_parser *); (cp_parser *);
static tree cp_parser_class_head static tree cp_parser_class_head
(cp_parser *, bool *, tree *); (cp_parser *, bool *, tree *, tree *);
static enum tag_types cp_parser_class_key static enum tag_types cp_parser_class_key
(cp_parser *); (cp_parser *);
static void cp_parser_member_specification_opt static void cp_parser_member_specification_opt
...@@ -13090,13 +13090,15 @@ cp_parser_class_specifier (cp_parser* parser) ...@@ -13090,13 +13090,15 @@ cp_parser_class_specifier (cp_parser* parser)
bool saved_in_function_body; bool saved_in_function_body;
tree old_scope = NULL_TREE; tree old_scope = NULL_TREE;
tree scope = NULL_TREE; tree scope = NULL_TREE;
tree bases;
push_deferring_access_checks (dk_no_deferred); push_deferring_access_checks (dk_no_deferred);
/* Parse the class-head. */ /* Parse the class-head. */
type = cp_parser_class_head (parser, type = cp_parser_class_head (parser,
&nested_name_specifier_p, &nested_name_specifier_p,
&attributes); &attributes,
&bases);
/* If the class-head was a semantic disaster, skip the entire body /* If the class-head was a semantic disaster, skip the entire body
of the class. */ of the class. */
if (!type) if (!type)
...@@ -13113,6 +13115,19 @@ cp_parser_class_specifier (cp_parser* parser) ...@@ -13113,6 +13115,19 @@ cp_parser_class_specifier (cp_parser* parser)
return error_mark_node; return error_mark_node;
} }
/* Process the base classes. If they're invalid, skip the
entire class body. */
if (!xref_basetypes (type, bases))
{
cp_parser_skip_to_closing_brace (parser);
/* Consuming the closing brace yields better error messages
later on. */
cp_lexer_consume_token (parser->lexer);
pop_deferring_access_checks ();
return error_mark_node;
}
/* Issue an error message if type-definitions are forbidden here. */ /* Issue an error message if type-definitions are forbidden here. */
cp_parser_check_type_definition (parser); cp_parser_check_type_definition (parser);
/* Remember that we are defining one more class. */ /* Remember that we are defining one more class. */
...@@ -13268,7 +13283,8 @@ cp_parser_class_specifier (cp_parser* parser) ...@@ -13268,7 +13283,8 @@ cp_parser_class_specifier (cp_parser* parser)
static tree static tree
cp_parser_class_head (cp_parser* parser, cp_parser_class_head (cp_parser* parser,
bool* nested_name_specifier_p, bool* nested_name_specifier_p,
tree *attributes_p) tree *attributes_p,
tree *bases)
{ {
tree nested_name_specifier; tree nested_name_specifier;
enum tag_types class_key; enum tag_types class_key;
...@@ -13281,7 +13297,6 @@ cp_parser_class_head (cp_parser* parser, ...@@ -13281,7 +13297,6 @@ cp_parser_class_head (cp_parser* parser,
bool invalid_explicit_specialization_p = false; bool invalid_explicit_specialization_p = false;
tree pushed_scope = NULL_TREE; tree pushed_scope = NULL_TREE;
unsigned num_templates; unsigned num_templates;
tree bases;
/* Assume no nested-name-specifier will be present. */ /* Assume no nested-name-specifier will be present. */
*nested_name_specifier_p = false; *nested_name_specifier_p = false;
...@@ -13569,6 +13584,8 @@ cp_parser_class_head (cp_parser* parser, ...@@ -13569,6 +13584,8 @@ cp_parser_class_head (cp_parser* parser,
type = NULL_TREE; type = NULL_TREE;
goto done; goto done;
} }
else if (type == error_mark_node)
type = NULL_TREE;
/* We will have entered the scope containing the class; the names of /* We will have entered the scope containing the class; the names of
base classes should be looked up in that context. For example: base classes should be looked up in that context. For example:
...@@ -13577,15 +13594,11 @@ cp_parser_class_head (cp_parser* parser, ...@@ -13577,15 +13594,11 @@ cp_parser_class_head (cp_parser* parser,
struct A::C : B {}; struct A::C : B {};
is valid. */ is valid. */
bases = NULL_TREE; *bases = NULL_TREE;
/* Get the list of base-classes, if there is one. */ /* Get the list of base-classes, if there is one. */
if (cp_lexer_next_token_is (parser->lexer, CPP_COLON)) if (cp_lexer_next_token_is (parser->lexer, CPP_COLON))
bases = cp_parser_base_clause (parser); *bases = cp_parser_base_clause (parser);
/* Process the base classes. */
if (!xref_basetypes (type, bases))
type = NULL_TREE;
done: done:
/* Leave the scope given by the nested-name-specifier. We will /* Leave the scope given by the nested-name-specifier. We will
......
2006-11-29 Lee Millward <lee.millward@codesourcery.com>
PR c++/29022
* g++.dg/inherit/virtual2.C: New test.
* g++.dg/inherit/virtual3.C: Likewise.
* g++.old-deja/g++.bugs/900121_05.C: Adjust error markers.
* g++.dg/inherit/error2.C: Likewise.
* g++.dg/template/instantiate1.C: Likewise.
2006-11-28 Andrew Pinski <pinskia@gmail.com> 2006-11-28 Andrew Pinski <pinskia@gmail.com>
PR tree-opt/29984 PR tree-opt/29984
...@@ -3,14 +3,14 @@ ...@@ -3,14 +3,14 @@
struct A struct A
{ {
virtual A* foo(); virtual A* foo(); // { dg-error "overriding" }
}; };
struct B : virtual A; // { dg-error "before" } struct B : virtual A; // { dg-error "before" }
struct C : A struct C : A
{ {
virtual B* foo(); virtual B* foo(); // { dg-error "invalid covariant" }
}; };
B* C::foo() { return 0; } B* C::foo() { return 0; }
//PR c++/29022
struct A
{
operator int();
};
struct B : virtual A, A<0> {}; // { dg-error "token" }
int foo(B &b)
{
return b; // { dg-error "cannot convert" }
}
//PR c++/29022
struct A
{
operator int();
};
struct B : virtual A; // { dg-error "token" }
int foo(B &b)
{
return b; // { dg-error "cannot convert" }
}
...@@ -16,6 +16,6 @@ template <class T> struct Z { // { dg-error "declaration" } ...@@ -16,6 +16,6 @@ template <class T> struct Z { // { dg-error "declaration" }
Y<Z<T> > y; // { dg-error "instantiated" } Y<Z<T> > y; // { dg-error "instantiated" }
}; };
struct ZZ : Z<int> // { dg-error "instantiated" } struct ZZ : Z<int>
{ {
}; };
...@@ -24,7 +24,7 @@ union u1 { ...@@ -24,7 +24,7 @@ union u1 {
int u1_member_1; int u1_member_1;
}; };
struct s1 : public u1 { /* { dg-error "" } base class is a union */ struct s1 : public u1 { /* { dg-error "base type" } */
int s1_member_0; int s1_member_0;
}; };
......
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