]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
cp-tree.h (convert_to_base_statically): Declare.
authorMark Mitchell <mark@codesourcery.com>
Thu, 24 Jul 2003 23:33:26 +0000 (23:33 +0000)
committerMark Mitchell <mmitchel@gcc.gnu.org>
Thu, 24 Jul 2003 23:33:26 +0000 (23:33 +0000)
* cp-tree.h (convert_to_base_statically): Declare.
* call.c (build_special_member_call): Convert INSTANCE to the base
type.
* class.c (convert_to_base_statically): New method.
* init.c (construct_virtual_base): Use it.
* method.c (do_build_assign_ref): Fix typo in comment.

* g++.dg/inherit/access5.C: New test.

From-SVN: r69763

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

index c9930bba76c7f68c20f60e6992c9fd64727b96e4..a4e454bf814075e122c0fbbec31e159177107dfa 100644 (file)
@@ -1,3 +1,12 @@
+2003-07-24  Mark Mitchell  <mark@codesourcery.com>
+
+       * cp-tree.h (convert_to_base_statically): Declare.
+       * call.c (build_special_member_call): Convert INSTANCE to the base
+       type.
+       * class.c (convert_to_base_statically): New method.
+       * init.c (construct_virtual_base): Use it.
+       * method.c (do_build_assign_ref): Fix typo in comment.
+
 2003-07-24  Jason Merrill  <jason@redhat.com>
 
        * decl.c: Just set truthvalue_* to boolean_*.
index 11e8d2e0cabdc05690f88fc435a7e9d2d16627dc..58888eacf521aab579f285ba46649ef61eb11281 100644 (file)
@@ -4747,11 +4747,23 @@ build_special_member_call (tree instance, tree name, tree args,
       TREE_TYPE (instance) = build_pointer_type (class_type);
       instance = build1 (INDIRECT_REF, class_type, instance);
     }
-  else if (name == complete_dtor_identifier 
-          || name == base_dtor_identifier
-          || name == deleting_dtor_identifier)
-    my_friendly_assert (args == NULL_TREE, 20020712);
+  else
+    {
+      if (name == complete_dtor_identifier 
+         || name == base_dtor_identifier
+         || name == deleting_dtor_identifier)
+       my_friendly_assert (args == NULL_TREE, 20020712);
 
+      /* We must perform the conversion here so that we do not
+        subsequently check to see whether BINFO is an accessible
+        base.  (It is OK for a constructor to call a constructor in
+        an inaccessible base as long as the constructor being called
+        is accessible.)  */
+      if (!same_type_ignoring_top_level_qualifiers_p 
+         (TREE_TYPE (instance), BINFO_TYPE (binfo)))
+       instance = convert_to_base_statically (instance, binfo);
+    }
+  
   my_friendly_assert (instance != NULL_TREE, 20020712);
 
   /* Resolve the name.  */
@@ -4787,7 +4799,9 @@ build_special_member_call (tree instance, tree name, tree args,
       args = tree_cons (NULL_TREE, sub_vtt, args);
     }
 
-  return build_new_method_call (instance, fns, args, binfo, flags);
+  return build_new_method_call (instance, fns, args, 
+                               TYPE_BINFO (BINFO_TYPE (binfo)), 
+                               flags);
 }
 
 /* Return the NAME, as a C string.  The NAME indicates a function that
index 4c46d1c9c66aceb70f3fbe0b1bd3b4a145cce1ae..d2fb90283dbcfb61ff3350a0f6980ac4e2952679 100644 (file)
@@ -391,6 +391,33 @@ convert_to_base (tree object, tree type, bool check_access)
   return build_base_path (PLUS_EXPR, object, binfo, /*nonnull=*/1);
 }
 
+/* EXPR is an expression with class type.  BASE is a base class (a
+   BINFO) of that class type.  Returns EXPR, converted to the BASE
+   type.  This function assumes that EXPR is the most derived class;
+   therefore virtual bases can be found at their static offsets.  */
+
+tree
+convert_to_base_statically (tree expr, tree base)
+{
+  tree expr_type;
+
+  expr_type = TREE_TYPE (expr);
+  if (!same_type_p (expr_type, BINFO_TYPE (base)))
+    {
+      tree pointer_type;
+
+      pointer_type = build_pointer_type (expr_type);
+      expr = build_unary_op (ADDR_EXPR, expr, /*noconvert=*/1);
+      if (!integer_zerop (BINFO_OFFSET (base)))
+         expr = build (PLUS_EXPR, pointer_type, expr, 
+                       build_nop (pointer_type, BINFO_OFFSET (base)));
+      expr = build_nop (build_pointer_type (BINFO_TYPE (base)), expr);
+      expr = build1 (INDIRECT_REF, BINFO_TYPE (base), expr);
+    }
+
+  return expr;
+}
+
 \f
 /* Virtual function things.  */
 
index 8e3fcf7701a9b3a6bb88b82c7e02cc0e51ccdd7c..8f543b4317e228d12af944989d45383f10d0e5e1 100644 (file)
@@ -3561,6 +3561,7 @@ extern tree build_cxx_call (tree, tree, tree);
 /* in class.c */
 extern tree build_base_path                    (enum tree_code, tree, tree, int);
 extern tree convert_to_base                     (tree, tree, bool);
+extern tree convert_to_base_statically (tree, tree);
 extern tree build_vtbl_ref                     (tree, tree);
 extern tree build_vfn_ref                      (tree, tree);
 extern tree get_vtable_decl                     (tree, int);
index fc10a24940b7ed5e494ca7346337f373fb4b145a..054ff30cd542da7aa33584895e0841ad430cf2f7 100644 (file)
@@ -863,18 +863,10 @@ construct_virtual_base (tree vbase, tree arguments)
      constructing virtual bases, then we must be the most derived
      class.  Therefore, we don't have to look up the virtual base;
      we already know where it is.  */
-  exp = build (PLUS_EXPR,
-              TREE_TYPE (current_class_ptr),
-              current_class_ptr,
-              fold (build1 (NOP_EXPR, TREE_TYPE (current_class_ptr),
-                            BINFO_OFFSET (vbase))));
-  exp = build1 (NOP_EXPR, 
-               build_pointer_type (BINFO_TYPE (vbase)), 
-               exp);
-  exp = build1 (INDIRECT_REF, BINFO_TYPE (vbase), exp);
-
-  expand_aggr_init_1 (vbase, current_class_ref, exp,
-                     arguments, LOOKUP_COMPLAIN);
+  exp = convert_to_base_statically (current_class_ref, vbase);
+
+  expand_aggr_init_1 (vbase, current_class_ref, exp, arguments, 
+                     LOOKUP_COMPLAIN);
   finish_compound_stmt (/*has_no_scope=*/1, compound_stmt);
   finish_then_clause (inner_if_stmt);
   finish_if_stmt ();
index 35319de9346c2a7af567a582c288103800502200..00428b1348d4b5b58401716f4e0968d83e286d7a 100644 (file)
@@ -605,7 +605,7 @@ do_build_assign_ref (tree fndecl)
       int cvquals = cp_type_quals (TREE_TYPE (parm));
       int i;
 
-      /* Assign to each of thedirect base classes.  */
+      /* Assign to each of the direct base classes.  */
       for (i = 0; i < CLASSTYPE_N_BASECLASSES (current_class_type); ++i)
        {
          tree binfo;
index a362729dc8413533b9d5df247e81caa01875a72d..0dcc60fc6e597e157c05332b1bee8ee071eabdd4 100644 (file)
@@ -1,3 +1,7 @@
+2003-07-24  Mark Mitchell  <mark@codesourcery.com>
+
+       * g++.dg/inherit/access5.C: New test.
+
 2003-07-24  Kriang Lerdsuwanakij  <lerdsuwa@users.sourceforge.net>
 
        PR c++/11513
diff --git a/gcc/testsuite/g++.dg/inherit/access5.C b/gcc/testsuite/g++.dg/inherit/access5.C
new file mode 100644 (file)
index 0000000..715a4a3
--- /dev/null
@@ -0,0 +1,4 @@
+struct S { ~S(); };
+struct T : virtual private S {};
+struct U : private T {};
+U u;