From: Lee Millward Date: Wed, 29 Nov 2006 15:19:39 +0000 (+0000) Subject: re PR c++/29022 (ICE using operator int in invalid class hierarchy) X-Git-Tag: releases/gcc-4.3.0~8231 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=7f9faf5e703dcc04ddf7dd8136095f3d1fbbed33;p=thirdparty%2Fgcc.git 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 --- diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 361d6f734ee6..149516cd9052 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,12 @@ +2006-11-29 Lee Millward + + 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 PR c++/29735 diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index b6b1c9729210..ad4d454baaf1 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -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 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index a08b86a37bd9..64bea987349b 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,12 @@ +2006-11-29 Lee Millward + + 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 PR tree-opt/29984 diff --git a/gcc/testsuite/g++.dg/inherit/error2.C b/gcc/testsuite/g++.dg/inherit/error2.C index 5a7c2940d272..7d5e2e5d689f 100644 --- a/gcc/testsuite/g++.dg/inherit/error2.C +++ b/gcc/testsuite/g++.dg/inherit/error2.C @@ -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; } diff --git a/gcc/testsuite/g++.dg/inherit/virtual2.C b/gcc/testsuite/g++.dg/inherit/virtual2.C new file mode 100644 index 000000000000..9769d4ab730c --- /dev/null +++ b/gcc/testsuite/g++.dg/inherit/virtual2.C @@ -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" } +} diff --git a/gcc/testsuite/g++.dg/inherit/virtual3.C b/gcc/testsuite/g++.dg/inherit/virtual3.C new file mode 100644 index 000000000000..65ae76c0b3db --- /dev/null +++ b/gcc/testsuite/g++.dg/inherit/virtual3.C @@ -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" } +} diff --git a/gcc/testsuite/g++.dg/template/instantiate1.C b/gcc/testsuite/g++.dg/template/instantiate1.C index 311344d9451d..0c739d0f6155 100644 --- a/gcc/testsuite/g++.dg/template/instantiate1.C +++ b/gcc/testsuite/g++.dg/template/instantiate1.C @@ -16,6 +16,6 @@ template struct Z { // { dg-error "declaration" } Y > y; // { dg-error "instantiated" } }; -struct ZZ : Z // { dg-error "instantiated" } +struct ZZ : Z { }; diff --git a/gcc/testsuite/g++.old-deja/g++.bugs/900121_05.C b/gcc/testsuite/g++.old-deja/g++.bugs/900121_05.C index 8dbae5df5b64..62db5b343afe 100644 --- a/gcc/testsuite/g++.old-deja/g++.bugs/900121_05.C +++ b/gcc/testsuite/g++.old-deja/g++.bugs/900121_05.C @@ -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; };