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
This commit is contained in:
Lee Millward 2006-11-29 15:19:39 +00:00 committed by Lee Millward
parent 8b65a354f0
commit 7f9faf5e70
8 changed files with 71 additions and 14 deletions

View File

@ -1,3 +1,12 @@
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>
PR c++/29735

View File

@ -1639,7 +1639,7 @@ static tree cp_parser_class_name
static tree cp_parser_class_specifier
(cp_parser *);
static tree cp_parser_class_head
(cp_parser *, bool *, tree *);
(cp_parser *, bool *, tree *, tree *);
static enum tag_types cp_parser_class_key
(cp_parser *);
static void cp_parser_member_specification_opt
@ -13090,13 +13090,15 @@ cp_parser_class_specifier (cp_parser* parser)
bool saved_in_function_body;
tree old_scope = NULL_TREE;
tree scope = NULL_TREE;
tree bases;
push_deferring_access_checks (dk_no_deferred);
/* Parse the class-head. */
type = cp_parser_class_head (parser,
&nested_name_specifier_p,
&attributes);
&attributes,
&bases);
/* If the class-head was a semantic disaster, skip the entire body
of the class. */
if (!type)
@ -13113,6 +13115,19 @@ cp_parser_class_specifier (cp_parser* parser)
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. */
cp_parser_check_type_definition (parser);
/* Remember that we are defining one more class. */
@ -13268,7 +13283,8 @@ cp_parser_class_specifier (cp_parser* parser)
static tree
cp_parser_class_head (cp_parser* parser,
bool* nested_name_specifier_p,
tree *attributes_p)
tree *attributes_p,
tree *bases)
{
tree nested_name_specifier;
enum tag_types class_key;
@ -13281,7 +13297,6 @@ cp_parser_class_head (cp_parser* parser,
bool invalid_explicit_specialization_p = false;
tree pushed_scope = NULL_TREE;
unsigned num_templates;
tree bases;
/* Assume no nested-name-specifier will be present. */
*nested_name_specifier_p = false;
@ -13569,6 +13584,8 @@ cp_parser_class_head (cp_parser* parser,
type = NULL_TREE;
goto done;
}
else if (type == error_mark_node)
type = NULL_TREE;
/* We will have entered the scope containing the class; the names of
base classes should be looked up in that context. For example:
@ -13577,15 +13594,11 @@ cp_parser_class_head (cp_parser* parser,
struct A::C : B {};
is valid. */
bases = NULL_TREE;
*bases = NULL_TREE;
/* Get the list of base-classes, if there is one. */
if (cp_lexer_next_token_is (parser->lexer, CPP_COLON))
bases = cp_parser_base_clause (parser);
/* Process the base classes. */
if (!xref_basetypes (type, bases))
type = NULL_TREE;
*bases = cp_parser_base_clause (parser);
done:
/* Leave the scope given by the nested-name-specifier. We will

View File

@ -1,3 +1,12 @@
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>
PR tree-opt/29984

View File

@ -3,14 +3,14 @@
struct A
{
virtual A* foo();
virtual A* foo(); // { dg-error "overriding" }
};
struct B : virtual A; // { dg-error "before" }
struct C : A
{
virtual B* foo();
virtual B* foo(); // { dg-error "invalid covariant" }
};
B* C::foo() { return 0; }

View File

@ -0,0 +1,13 @@
//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" }
}

View File

@ -0,0 +1,13 @@
//PR c++/29022
struct A
{
operator int();
};
struct B : virtual A; // { dg-error "token" }
int foo(B &b)
{
return b; // { dg-error "cannot convert" }
}

View File

@ -16,6 +16,6 @@ template <class T> struct Z { // { dg-error "declaration" }
Y<Z<T> > y; // { dg-error "instantiated" }
};
struct ZZ : Z<int> // { dg-error "instantiated" }
struct ZZ : Z<int>
{
};

View File

@ -24,7 +24,7 @@ union u1 {
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;
};