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:
parent
aecf642c78
commit
22ed7e5f2c
|
@ -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_*.
|
||||
|
|
|
@ -4747,10 +4747,22 @@ 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);
|
||||
|
||||
|
@ -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
|
||||
|
|
|
@ -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. */
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 ();
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
struct S { ~S(); };
|
||||
struct T : virtual private S {};
|
||||
struct U : private T {};
|
||||
U u;
|
Loading…
Reference in New Issue