* 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
+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_*.
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. */
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
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. */
/* 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);
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 ();
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;
+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
--- /dev/null
+struct S { ~S(); };
+struct T : virtual private S {};
+struct U : private T {};
+U u;