cp-tree.h (convert_to_base_statically): Declare.

* 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
This commit is contained in:
Mark Mitchell 2003-07-24 23:33:26 +00:00 committed by Mark Mitchell
parent aecf642c78
commit 22ed7e5f2c
8 changed files with 68 additions and 17 deletions

View 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_*.

View 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

View 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;
}
/* Virtual function things. */

View 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);

View 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);
exp = convert_to_base_statically (current_class_ref, vbase);
expand_aggr_init_1 (vbase, current_class_ref, exp,
arguments, LOOKUP_COMPLAIN);
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 ();

View 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;

View 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

View File

@ -0,0 +1,4 @@
struct S { ~S(); };
struct T : virtual private S {};
struct U : private T {};
U u;