]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR c++/29022 (ICE using operator int in invalid class hierarchy)
authorLee Millward <lee.millward@codesourcery.com>
Wed, 29 Nov 2006 15:19:39 +0000 (15:19 +0000)
committerLee Millward <lmillward@gcc.gnu.org>
Wed, 29 Nov 2006 15:19:39 +0000 (15:19 +0000)
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

gcc/cp/ChangeLog
gcc/cp/parser.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/inherit/error2.C
gcc/testsuite/g++.dg/inherit/virtual2.C [new file with mode: 0644]
gcc/testsuite/g++.dg/inherit/virtual3.C [new file with mode: 0644]
gcc/testsuite/g++.dg/template/instantiate1.C
gcc/testsuite/g++.old-deja/g++.bugs/900121_05.C

index 361d6f734ee6c3944f60aed8669a712205b7e926..149516cd9052f77ab6db13a98a891647d8cd48fe 100644 (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
index b6b1c9729210db0c72eda4c665cb3bc34894d576..ad4d454baaf1100fe33766911d84a04a294a7b97 100644 (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
index a08b86a37bd9b23fa65a8f01ad525fa11a346110..64bea987349bde763d64fcdba702d353aae2c006 100644 (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
index 5a7c2940d272a8d8739b47de876aef719e3a723b..7d5e2e5d689fe940d4e4dc6e40d8b2005344d295 100644 (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; }
diff --git a/gcc/testsuite/g++.dg/inherit/virtual2.C b/gcc/testsuite/g++.dg/inherit/virtual2.C
new file mode 100644 (file)
index 0000000..9769d4a
--- /dev/null
@@ -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 (file)
index 0000000..65ae76c
--- /dev/null
@@ -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" }
+}
index 311344d9451dacee895dc63ae0deb6099f1df560..0c739d0f61550a5724bbebc8e434af679dc6ad13 100644 (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>
 {
 };
index 8dbae5df5b64ca39702babf7d66e18d78f5a95f2..62db5b343afed32430aaae18e27b75861ab894ec 100644 (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;
 };