Commit 22ed7e5f by Mark Mitchell Committed by Mark Mitchell

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
parent aecf642c
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> 2003-07-24 Jason Merrill <jason@redhat.com>
* decl.c: Just set truthvalue_* to boolean_*. * decl.c: Just set truthvalue_* to boolean_*.
......
...@@ -4747,11 +4747,23 @@ build_special_member_call (tree instance, tree name, tree args, ...@@ -4747,11 +4747,23 @@ build_special_member_call (tree instance, tree name, tree args,
TREE_TYPE (instance) = build_pointer_type (class_type); TREE_TYPE (instance) = build_pointer_type (class_type);
instance = build1 (INDIRECT_REF, class_type, instance); instance = build1 (INDIRECT_REF, class_type, instance);
} }
else if (name == complete_dtor_identifier else
{
if (name == complete_dtor_identifier
|| name == base_dtor_identifier || name == base_dtor_identifier
|| name == deleting_dtor_identifier) || name == deleting_dtor_identifier)
my_friendly_assert (args == NULL_TREE, 20020712); 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); my_friendly_assert (instance != NULL_TREE, 20020712);
/* Resolve the name. */ /* Resolve the name. */
...@@ -4787,7 +4799,9 @@ build_special_member_call (tree instance, tree name, tree args, ...@@ -4787,7 +4799,9 @@ build_special_member_call (tree instance, tree name, tree args,
args = tree_cons (NULL_TREE, sub_vtt, 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 /* Return the NAME, as a C string. The NAME indicates a function that
......
...@@ -391,6 +391,33 @@ convert_to_base (tree object, tree type, bool check_access) ...@@ -391,6 +391,33 @@ convert_to_base (tree object, tree type, bool check_access)
return build_base_path (PLUS_EXPR, object, binfo, /*nonnull=*/1); 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. */ /* Virtual function things. */
......
...@@ -3561,6 +3561,7 @@ extern tree build_cxx_call (tree, tree, tree); ...@@ -3561,6 +3561,7 @@ extern tree build_cxx_call (tree, tree, tree);
/* in class.c */ /* in class.c */
extern tree build_base_path (enum tree_code, tree, tree, int); extern tree build_base_path (enum tree_code, tree, tree, int);
extern tree convert_to_base (tree, tree, bool); 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_vtbl_ref (tree, tree);
extern tree build_vfn_ref (tree, tree); extern tree build_vfn_ref (tree, tree);
extern tree get_vtable_decl (tree, int); extern tree get_vtable_decl (tree, int);
......
...@@ -863,18 +863,10 @@ construct_virtual_base (tree vbase, tree arguments) ...@@ -863,18 +863,10 @@ construct_virtual_base (tree vbase, tree arguments)
constructing virtual bases, then we must be the most derived constructing virtual bases, then we must be the most derived
class. Therefore, we don't have to look up the virtual base; class. Therefore, we don't have to look up the virtual base;
we already know where it is. */ we already know where it is. */
exp = build (PLUS_EXPR, exp = convert_to_base_statically (current_class_ref, vbase);
TREE_TYPE (current_class_ptr),
current_class_ptr, expand_aggr_init_1 (vbase, current_class_ref, exp, arguments,
fold (build1 (NOP_EXPR, TREE_TYPE (current_class_ptr), LOOKUP_COMPLAIN);
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);
finish_compound_stmt (/*has_no_scope=*/1, compound_stmt); finish_compound_stmt (/*has_no_scope=*/1, compound_stmt);
finish_then_clause (inner_if_stmt); finish_then_clause (inner_if_stmt);
finish_if_stmt (); finish_if_stmt ();
......
...@@ -605,7 +605,7 @@ do_build_assign_ref (tree fndecl) ...@@ -605,7 +605,7 @@ do_build_assign_ref (tree fndecl)
int cvquals = cp_type_quals (TREE_TYPE (parm)); int cvquals = cp_type_quals (TREE_TYPE (parm));
int i; 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) for (i = 0; i < CLASSTYPE_N_BASECLASSES (current_class_type); ++i)
{ {
tree binfo; 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> 2003-07-24 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
PR c++/11513 PR c++/11513
......
struct S { ~S(); };
struct T : virtual private S {};
struct U : private T {};
U u;
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment