mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-03-23 00:41:25 +08:00
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:
parent
8b65a354f0
commit
7f9faf5e70
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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; }
|
||||
|
13
gcc/testsuite/g++.dg/inherit/virtual2.C
Normal file
13
gcc/testsuite/g++.dg/inherit/virtual2.C
Normal 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" }
|
||||
}
|
13
gcc/testsuite/g++.dg/inherit/virtual3.C
Normal file
13
gcc/testsuite/g++.dg/inherit/virtual3.C
Normal 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" }
|
||||
}
|
@ -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>
|
||||
{
|
||||
};
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user