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>
|
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,
|
||||||
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
|
||||||
|| name == base_dtor_identifier
|
{
|
||||||
|| name == deleting_dtor_identifier)
|
if (name == complete_dtor_identifier
|
||||||
my_friendly_assert (args == NULL_TREE, 20020712);
|
|| 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);
|
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,
|
||||||
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)
|
||||||
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);
|
||||||
/* 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)
|
||||||
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,
|
|
||||||
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,
|
expand_aggr_init_1 (vbase, current_class_ref, exp, arguments,
|
||||||
arguments, LOOKUP_COMPLAIN);
|
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)
|
||||||
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;
|
||||||
|
|
|
@ -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>
|
2003-07-24 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
|
||||||
|
|
||||||
PR c++/11513
|
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