aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLee Millward <lee.millward@codesourcery.com>2006-11-29 15:19:39 +0000
committerLee Millward <lmillward@gcc.gnu.org>2006-11-29 15:19:39 +0000
commit7f9faf5e703dcc04ddf7dd8136095f3d1fbbed33 (patch)
tree8dfe031c7bde6e8643739d129b93e39020aca30e
parent8b65a354f0a738cf9e1bfe507ce146ca56b518bc (diff)
downloadgcc-7f9faf5e703dcc04ddf7dd8136095f3d1fbbed33.zip
gcc-7f9faf5e703dcc04ddf7dd8136095f3d1fbbed33.tar.gz
gcc-7f9faf5e703dcc04ddf7dd8136095f3d1fbbed33.tar.bz2
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
-rw-r--r--gcc/cp/ChangeLog9
-rw-r--r--gcc/cp/parser.c33
-rw-r--r--gcc/testsuite/ChangeLog9
-rw-r--r--gcc/testsuite/g++.dg/inherit/error2.C4
-rw-r--r--gcc/testsuite/g++.dg/inherit/virtual2.C13
-rw-r--r--gcc/testsuite/g++.dg/inherit/virtual3.C13
-rw-r--r--gcc/testsuite/g++.dg/template/instantiate1.C2
-rw-r--r--gcc/testsuite/g++.old-deja/g++.bugs/900121_05.C2
8 files changed, 71 insertions, 14 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 361d6f7..149516c 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -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
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index b6b1c97..ad4d454 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 a08b86a..64bea98 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
diff --git a/gcc/testsuite/g++.dg/inherit/error2.C b/gcc/testsuite/g++.dg/inherit/error2.C
index 5a7c294..7d5e2e5 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 0000000..9769d4a
--- /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 0000000..65ae76c
--- /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 311344d..0c739d0 100644
--- a/gcc/testsuite/g++.dg/template/instantiate1.C
+++ b/gcc/testsuite/g++.dg/template/instantiate1.C
@@ -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>
{
};
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 8dbae5df..62db5b3 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;
};