PR c++/11789
authormmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 11 Aug 2003 02:49:44 +0000 (02:49 +0000)
committermmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 11 Aug 2003 02:49:44 +0000 (02:49 +0000)
* cp-tree.h (get_vbase): Remove.
(get_vbase_types): Remove.
* init.c (expand_member_init): Correct logic for looking up base
classes.

PR c++/11789.C
* g++.dg/inherit/multiple1.C: New test.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@70316 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/cp/ChangeLog
gcc/cp/cp-tree.h
gcc/cp/init.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/inherit/multiple1.C [new file with mode: 0644]

index fde090e..191879f 100644 (file)
@@ -1,3 +1,11 @@
+2003-08-10  Mark Mitchell  <mark@codesourcery.com>
+
+       PR c++/11789
+       * cp-tree.h (get_vbase): Remove.
+       (get_vbase_types): Remove.
+       * init.c (expand_member_init): Correct logic for looking up base
+       classes.
+
 2003-08-10  Gabriel Dos Reis  <gdr@integrable-solutions.net>
 
        * error.c (dump_expr): Tidy.
index d47c307..a740142 100644 (file)
@@ -4018,7 +4018,6 @@ extern bool emit_tinfo_decl (tree);
 extern bool accessible_base_p (tree, tree);
 extern tree lookup_base (tree, tree, base_access, base_kind *);
 extern int types_overlap_p                     (tree, tree);
-extern tree get_vbase                          (tree, tree);
 extern tree get_dynamic_cast_base_type          (tree, tree);
 extern int accessible_p                         (tree, tree);
 extern tree lookup_field_1                      (tree, tree, bool);
@@ -4028,7 +4027,6 @@ extern tree lookup_fnfields                       (tree, tree, int);
 extern tree lookup_member                      (tree, tree, int, bool);
 extern int look_for_overrides                  (tree, tree);
 extern void get_pure_virtuals                  (tree);
-extern void get_vbase_types                    (tree);
 extern void maybe_suppress_debug_info          (tree);
 extern void note_debug_info_needed             (tree);
 extern void push_class_decls                   (tree);
index 1774af4..9582451 100644 (file)
@@ -963,16 +963,50 @@ expand_member_init (tree name)
 
   if (basetype)
     {
-      tree binfo;
+      tree class_binfo;
+      tree direct_binfo;
+      tree virtual_binfo;
+      int i;
 
       if (current_template_parms)
        return basetype;
 
-      binfo = lookup_base (current_class_type, basetype, 
-                          ba_ignore, NULL);
-      if (!binfo || (!TREE_VIA_VIRTUAL (binfo)
-                    && (BINFO_INHERITANCE_CHAIN (binfo)
-                        != TYPE_BINFO (current_class_type))))
+      class_binfo = TYPE_BINFO (current_class_type);
+      direct_binfo = NULL_TREE;
+      virtual_binfo = NULL_TREE;
+
+      /* Look for a direct base.  */
+      for (i = 0; i < BINFO_N_BASETYPES (class_binfo); ++i)
+       if (same_type_p (basetype, 
+                        TYPE_BINFO_BASETYPE (current_class_type, i)))
+         {
+           direct_binfo = BINFO_BASETYPE (class_binfo, i);
+           break;
+         }
+      /* Look for a virtual base -- unless the direct base is itself
+        virtual.  */
+      if (!direct_binfo || !TREE_VIA_VIRTUAL (direct_binfo))
+       {
+         virtual_binfo 
+           = purpose_member (basetype,
+                             CLASSTYPE_VBASECLASSES (current_class_type));
+         if (virtual_binfo)
+           virtual_binfo = TREE_VALUE (virtual_binfo);
+       }
+
+      /* [class.base.init]
+        
+         If a mem-initializer-id is ambiguous because it designates
+        both a direct non-virtual base class and an inherited virtual
+        base class, the mem-initializer is ill-formed.  */
+      if (direct_binfo && virtual_binfo)
+       {
+         error ("'%D' is both a direct base and an indirect virtual base",
+                basetype);
+         return NULL_TREE;
+       }
+
+      if (!direct_binfo && !virtual_binfo)
        {
          if (TYPE_USES_VIRTUAL_BASECLASSES (current_class_type))
            error ("type `%D' is not a direct or virtual base of `%T'",
@@ -982,7 +1016,8 @@ expand_member_init (tree name)
                   name, current_class_type);
          return NULL_TREE;
        }
-      return binfo;
+
+      return direct_binfo ? direct_binfo : virtual_binfo;
     }
   else
     {
index 0c82d52..9580129 100644 (file)
@@ -1,3 +1,8 @@
+2003-08-10  Mark Mitchell  <mark@codesourcery.com>
+
+       PR c++/11789.C
+       * g++.dg/inherit/multiple1.C: New test.
+
 2003-08-10  Nathan Sidwell  <nathan@codesourcery.com>
 
        * gcc.dg/spe1.c: New test.
diff --git a/gcc/testsuite/g++.dg/inherit/multiple1.C b/gcc/testsuite/g++.dg/inherit/multiple1.C
new file mode 100644 (file)
index 0000000..3eb9fe7
--- /dev/null
@@ -0,0 +1,20 @@
+// { dg-options "-w" }
+
+struct Base {
+  int b;
+  
+  Base(int b) : b(b) { }
+};
+
+struct Derived : public Base {
+  Derived(int d) : Base(d) { }
+};
+
+struct Final : public Derived, public Base {
+  Final(int f) : Derived(f), Base(f-1) { }
+};
+
+int main()
+{
+  Final f(5);
+}