re PR c++/70202 (ICE on invalid code on x86_64-linux-gnu in build_simple_base_path...
authorPaolo Carlini <paolo.carlini@oracle.com>
Wed, 15 Jun 2016 15:23:40 +0000 (15:23 +0000)
committerPaolo Carlini <paolo@gcc.gnu.org>
Wed, 15 Jun 2016 15:23:40 +0000 (15:23 +0000)
/cp
2016-06-15  Paolo Carlini  <paolo.carlini@oracle.com>

PR c++/70202
* decl.c (xref_basetypes): Revert r117839 changes; add fix-up
code at the end of the for loop; also revert r159637 changes,
add back the gcc_assert.
* cp-tree.h (xref_basetypes): Adjust declaration.
* parser.c (cp_parser_class_head): Adjust xref_basetypes call.

/testsuite
2016-06-15  Paolo Carlini  <paolo.carlini@oracle.com>

PR c++/70202
* g++.dg/inherit/crash6.C: New.
* g++.dg/inherit/union2.C: Likewise.
* g++.dg/inherit/virtual12.C: Likewise.
* g++.dg/inherit/virtual13.C: Likewise.
* g++.dg/inherit/virtual1.C: Tweak dg-* tests.

From-SVN: r237482

gcc/cp/ChangeLog
gcc/cp/cp-tree.h
gcc/cp/decl.c
gcc/cp/parser.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/inherit/crash6.C [new file with mode: 0644]
gcc/testsuite/g++.dg/inherit/union2.C [new file with mode: 0644]
gcc/testsuite/g++.dg/inherit/virtual1.C
gcc/testsuite/g++.dg/inherit/virtual12.C [new file with mode: 0644]
gcc/testsuite/g++.dg/inherit/virtual13.C [new file with mode: 0644]

index 775b61482d496d27e17c8fbdc4f6d19900a30fa1..7e68d0541970164a88cbd7623610c5de6b370c72 100644 (file)
@@ -1,3 +1,12 @@
+2016-06-15  Paolo Carlini  <paolo.carlini@oracle.com>
+
+       PR c++/70202
+       * decl.c (xref_basetypes): Revert r117839 changes; add fix-up
+       code at the end of the for loop; also revert r159637 changes,
+       add back the gcc_assert.
+       * cp-tree.h (xref_basetypes): Adjust declaration.
+       * parser.c (cp_parser_class_head): Adjust xref_basetypes call.
+
 2016-06-14  David Malcolm  <dmalcolm@redhat.com>
 
        * search.c: Include spellcheck-tree.h rather than spellcheck.h.
index 6c6ad10804eb54b32436d0e5710fd7c231a4f7b2..5b87bb391d9697c93337ee8e8e7463cc20afb6b4 100644 (file)
@@ -5788,7 +5788,7 @@ extern int grok_ctor_properties                   (const_tree, const_tree);
 extern bool grok_op_properties                 (tree, bool);
 extern tree xref_tag                           (enum tag_types, tree, tag_scope, bool);
 extern tree xref_tag_from_type                 (tree, tree, tag_scope);
-extern bool xref_basetypes                     (tree, tree);
+extern void xref_basetypes                     (tree, tree);
 extern tree start_enum                         (tree, tree, tree, tree, bool, bool *);
 extern void finish_enum_value_list             (tree);
 extern void finish_enum                                (tree);
index a03e48ff6182410e75cd4df0f0ec8c4fafc29dca..1aa5e523cb33f01684e425db1d5921a3911a39be 100644 (file)
@@ -12879,12 +12879,9 @@ xref_tag_from_type (tree old, tree id, tag_scope scope)
 /* Create the binfo hierarchy for REF with (possibly NULL) base list
    BASE_LIST.  For each element on BASE_LIST the TREE_PURPOSE is an
    access_* node, and the TREE_VALUE is the type of the base-class.
-   Non-NULL TREE_TYPE indicates virtual inheritance.  
-   Returns true if the binfo hierarchy was successfully created,
-   false if an error was detected. */
+   Non-NULL TREE_TYPE indicates virtual inheritance.  */
 
-bool
+void
 xref_basetypes (tree ref, tree base_list)
 {
   tree *basep;
@@ -12897,7 +12894,7 @@ xref_basetypes (tree ref, tree base_list)
   tree igo_prev; /* Track Inheritance Graph Order.  */
 
   if (ref == error_mark_node)
-    return false;
+    return;
 
   /* The base of a derived class is private by default, all others are
      public.  */
@@ -12941,11 +12938,7 @@ xref_basetypes (tree ref, tree base_list)
 
   /* The binfo slot should be empty, unless this is an (ill-formed)
      redefinition.  */
-  if (TYPE_BINFO (ref) && !TYPE_SIZE (ref))
-    {
-      error ("redefinition of %q#T", ref);
-      return false;
-    }
+  gcc_assert (!TYPE_BINFO (ref) || TYPE_SIZE (ref));
 
   gcc_assert (TYPE_MAIN_VARIANT (ref) == ref);
 
@@ -12965,19 +12958,13 @@ xref_basetypes (tree ref, tree base_list)
       CLASSTYPE_NON_AGGREGATE (ref) = 1;
 
       if (TREE_CODE (ref) == UNION_TYPE)
-        {
-         error ("derived union %qT invalid", ref);
-          return false;
-        }
+       error ("derived union %qT invalid", ref);
     }
 
   if (max_bases > 1)
     {
       if (TYPE_FOR_JAVA (ref))
-        {
-         error ("Java class %qT cannot have multiple bases", ref);
-          return false;
-        }
+       error ("Java class %qT cannot have multiple bases", ref);
       else
        warning (OPT_Wmultiple_inheritance,
                 "%qT defined with multiple direct bases", ref);
@@ -12988,10 +12975,7 @@ xref_basetypes (tree ref, tree base_list)
       vec_alloc (CLASSTYPE_VBASECLASSES (ref), max_vbases);
 
       if (TYPE_FOR_JAVA (ref))
-        {
-         error ("Java class %qT cannot have virtual bases", ref);
-          return false;
-        }
+       error ("Java class %qT cannot have virtual bases", ref);
       else if (max_dvbases)
        warning (OPT_Wvirtual_inheritance,
                 "%qT defined with direct virtual base", ref);
@@ -13014,7 +12998,7 @@ xref_basetypes (tree ref, tree base_list)
        {
          error ("base type %qT fails to be a struct or class type",
                 basetype);
-         return false;
+         goto dropped_base;
        }
 
       if (TYPE_FOR_JAVA (basetype) && (current_lang_depth () == 0))
@@ -13048,7 +13032,7 @@ xref_basetypes (tree ref, tree base_list)
            error ("recursive type %qT undefined", basetype);
          else
            error ("duplicate base type %qT invalid", basetype);
-         return false;
+         goto dropped_base;
        }
 
       if (PACK_EXPANSION_P (TREE_VALUE (base_list)))
@@ -13064,8 +13048,25 @@ xref_basetypes (tree ref, tree base_list)
 
       BINFO_BASE_APPEND (binfo, base_binfo);
       BINFO_BASE_ACCESS_APPEND (binfo, access);
+      continue;
+
+    dropped_base:
+      /* Update max_vbases to reflect the reality that we are dropping
+        this base:  if it reaches zero we want to undo the vec_alloc
+        above to avoid inconsistencies during error-recovery: eg, in
+        build_special_member_call, CLASSTYPE_VBASECLASSES non null
+        and vtt null (c++/27952).  */
+      if (via_virtual)
+       max_vbases--;
+      if (CLASS_TYPE_P (basetype))
+       max_vbases
+         -= vec_safe_length (CLASSTYPE_VBASECLASSES (basetype));
     }
 
+  if (CLASSTYPE_VBASECLASSES (ref)
+      && max_vbases == 0)
+    vec_free (CLASSTYPE_VBASECLASSES (ref));
+
   if (vec_safe_length (CLASSTYPE_VBASECLASSES (ref)) < max_vbases)
     /* If we didn't get max_vbases vbases, we must have shared at
        least one of them, and are therefore diamond shaped.  */
@@ -13096,8 +13097,6 @@ xref_basetypes (tree ref, tree base_list)
        else
          break;
     }
-
-  return true;
 }
 
 \f
index 632b25fac95411adaf7066d9fbc85e536cff5a9c..a9c636b7f41fb9c4fa3a9f79f7987b7449659458 100644 (file)
@@ -22050,9 +22050,8 @@ cp_parser_class_head (cp_parser* parser,
 
   /* If we're really defining a class, process the base classes.
      If they're invalid, fail.  */
-  if (type && cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE)
-      && !xref_basetypes (type, bases))
-    type = NULL_TREE;
+  if (type && cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE))
+    xref_basetypes (type, bases);
 
  done:
   /* Leave the scope given by the nested-name-specifier.  We will
index 7b10f9736716f6bdf27293ff54d9f3a46c2b61e5..d9dd04db11833bbeabe572048ac6bbb2aefe3ab7 100644 (file)
@@ -1,3 +1,12 @@
+2016-06-15  Paolo Carlini  <paolo.carlini@oracle.com>
+
+       PR c++/70202
+       * g++.dg/inherit/crash6.C: New.
+       * g++.dg/inherit/union2.C: Likewise.
+       * g++.dg/inherit/virtual12.C: Likewise.
+       * g++.dg/inherit/virtual13.C: Likewise.
+       * g++.dg/inherit/virtual1.C: Tweak dg-* tests.
+
 2016-06-15  Uros Bizjak  <ubizjak@gmail.com>
 
         * gcc.dg/torture/float128-nan.c: Include stdint.h to define uint64_t.
diff --git a/gcc/testsuite/g++.dg/inherit/crash6.C b/gcc/testsuite/g++.dg/inherit/crash6.C
new file mode 100644 (file)
index 0000000..bce999c
--- /dev/null
@@ -0,0 +1,10 @@
+// PR c++/70202
+
+class A
+{
+  virtual void foo () { }
+};
+class B : public A, A { };  // { dg-error "duplicate base type" }
+
+B b1, &b2 = b1;
+A a = b2;
diff --git a/gcc/testsuite/g++.dg/inherit/union2.C b/gcc/testsuite/g++.dg/inherit/union2.C
new file mode 100644 (file)
index 0000000..e3a9130
--- /dev/null
@@ -0,0 +1,3 @@
+struct A { };
+union U : A { };  // { dg-error "derived union 'U' invalid" }
+U u;
index 08bcbb143cfb0a0557f4286587d1ec7f40599bcd..ed597e2a3d7ff69ce39a481155963211932404bd 100644 (file)
@@ -1,12 +1,12 @@
-//PR c++/27952
+// PR c++/27952
 
 struct A
 {
     virtual ~A() {}
 };
 
-struct B : A, virtual A {};     // { dg-error "duplicate base|forward declaration" }
+struct B : A, virtual A {};     // { dg-error "duplicate base" }
 
-struct C : A, B {};             // { dg-error "duplicate base|invalid use" }
+struct C : A, B {};             // { dg-message "direct base 'A' inaccessible" }
 
-C c;                            // { dg-error "aggregate" }
+C c;
diff --git a/gcc/testsuite/g++.dg/inherit/virtual12.C b/gcc/testsuite/g++.dg/inherit/virtual12.C
new file mode 100644 (file)
index 0000000..3e96d2e
--- /dev/null
@@ -0,0 +1,14 @@
+// PR c++/70202
+
+union U { };
+
+struct A
+{
+  virtual ~A() {}
+};
+
+struct B : A, virtual U { };  // { dg-error "base type 'U' fails" }
+
+struct C : A, B {};  // { dg-message "direct base 'A' inaccessible" }
+
+C c;
diff --git a/gcc/testsuite/g++.dg/inherit/virtual13.C b/gcc/testsuite/g++.dg/inherit/virtual13.C
new file mode 100644 (file)
index 0000000..ca504eb
--- /dev/null
@@ -0,0 +1,16 @@
+// PR c++/70202
+
+struct D { };
+
+union U : virtual D { };  // { dg-error "derived union" }
+
+struct A
+{
+  virtual ~A() {}
+};
+
+struct B : A, virtual U { };  // { dg-error "base type 'U' fails" }
+
+struct C : A, B {};  // { dg-message "direct base 'A' inaccessible" }
+
+C c;