re PR c++/17386 (libstdc++ iostreams miscompilation)
PR c++/17386 * call.c (build_vfield_ref): Move... * class.c (build_vfield_ref): ... here. Convert datum to the primary base containing the vptr. (make_new_vtable): Simplify build_primary_vtable arguments. (finish_struct_1): Do not duplicate TYPE_VFIELD. * typeck.c (build_class_member_access_expr): Don't warn for null object access to base fields. From-SVN: r87322
This commit is contained in:
parent
80aa8340eb
commit
981c353ef5
@ -1,3 +1,14 @@
|
||||
2004-09-10 Richard Henderson <rth@redhat.com>
|
||||
|
||||
PR c++/17386
|
||||
* call.c (build_vfield_ref): Move...
|
||||
* class.c (build_vfield_ref): ... here. Convert datum to the
|
||||
primary base containing the vptr.
|
||||
(make_new_vtable): Simplify build_primary_vtable arguments.
|
||||
(finish_struct_1): Do not duplicate TYPE_VFIELD.
|
||||
* typeck.c (build_class_member_access_expr): Don't warn for
|
||||
null object access to base fields.
|
||||
|
||||
2004-09-10 Ziemowit Laski <zlaski@apple.com>
|
||||
|
||||
* decl.c (objc_get_current_scope, objc_mark_locals_volatile):
|
||||
|
@ -191,23 +191,6 @@ static bool magic_varargs_p (tree);
|
||||
static tree build_temp (tree, tree, int, void (**)(const char *, ...));
|
||||
static void check_constructor_callable (tree, tree);
|
||||
|
||||
tree
|
||||
build_vfield_ref (tree datum, tree type)
|
||||
{
|
||||
if (datum == error_mark_node)
|
||||
return error_mark_node;
|
||||
|
||||
if (TREE_CODE (TREE_TYPE (datum)) == REFERENCE_TYPE)
|
||||
datum = convert_from_reference (datum);
|
||||
|
||||
if (TYPE_BASE_CONVS_MAY_REQUIRE_CODE_P (type)
|
||||
&& !same_type_ignoring_top_level_qualifiers_p (TREE_TYPE (datum), type))
|
||||
datum = convert_to_base (datum, type, /*check_access=*/false);
|
||||
|
||||
return build3 (COMPONENT_REF, TREE_TYPE (TYPE_VFIELD (type)),
|
||||
datum, TYPE_VFIELD (type), NULL_TREE);
|
||||
}
|
||||
|
||||
/* Returns nonzero iff the destructor name specified in NAME
|
||||
(a BIT_NOT_EXPR) matches BASETYPE. The operand of NAME can take many
|
||||
forms... */
|
||||
|
@ -483,6 +483,38 @@ convert_to_base_statically (tree expr, tree base)
|
||||
}
|
||||
|
||||
|
||||
tree
|
||||
build_vfield_ref (tree datum, tree type)
|
||||
{
|
||||
tree vfield, vcontext;
|
||||
|
||||
if (datum == error_mark_node)
|
||||
return error_mark_node;
|
||||
|
||||
if (TREE_CODE (TREE_TYPE (datum)) == REFERENCE_TYPE)
|
||||
datum = convert_from_reference (datum);
|
||||
|
||||
/* First, convert to the requested type. */
|
||||
if (!same_type_ignoring_top_level_qualifiers_p (TREE_TYPE (datum), type))
|
||||
datum = convert_to_base (datum, type, /*check_access=*/false);
|
||||
|
||||
/* Second, the requested type may not be the owner of its own vptr.
|
||||
If not, convert to the base class that owns it. We cannot use
|
||||
convert_to_base here, because VCONTEXT may appear more than once
|
||||
in the inheritence hierarchy of TYPE, and thus direct conversion
|
||||
between the types may be ambiguous. Following the path back up
|
||||
one step at a time via primary bases avoids the problem. */
|
||||
vfield = TYPE_VFIELD (type);
|
||||
vcontext = DECL_CONTEXT (vfield);
|
||||
while (!same_type_ignoring_top_level_qualifiers_p (vcontext, type))
|
||||
{
|
||||
datum = build_simple_base_path (datum, CLASSTYPE_PRIMARY_BINFO (type));
|
||||
type = TREE_TYPE (datum);
|
||||
}
|
||||
|
||||
return build3 (COMPONENT_REF, TREE_TYPE (vfield), datum, vfield, NULL_TREE);
|
||||
}
|
||||
|
||||
/* Given an object INSTANCE, return an expression which yields the
|
||||
vtable element corresponding to INDEX. There are many special
|
||||
cases for INSTANCE which we take care of here, mainly to avoid
|
||||
@ -783,10 +815,7 @@ make_new_vtable (tree t, tree binfo)
|
||||
/* In this case, it is *type*'s vtable we are modifying. We start
|
||||
with the approximation that its vtable is that of the
|
||||
immediate base class. */
|
||||
/* ??? This actually passes TYPE_BINFO (t), not the primary base binfo,
|
||||
since we've updated DECL_CONTEXT (TYPE_VFIELD (t)) by now. */
|
||||
return build_primary_vtable (TYPE_BINFO (DECL_CONTEXT (TYPE_VFIELD (t))),
|
||||
t);
|
||||
return build_primary_vtable (binfo, t);
|
||||
else
|
||||
/* This is our very own copy of `basetype' to play with. Later,
|
||||
we will fill in all the virtual functions that override the
|
||||
@ -4927,7 +4956,6 @@ finish_struct_1 (tree t)
|
||||
/* A TREE_LIST. The TREE_VALUE of each node is a FUNCTION_DECL. */
|
||||
tree virtuals = NULL_TREE;
|
||||
int n_fields = 0;
|
||||
tree vfield;
|
||||
|
||||
if (COMPLETE_TYPE_P (t))
|
||||
{
|
||||
@ -4981,25 +5009,6 @@ finish_struct_1 (tree t)
|
||||
needs a mode. */
|
||||
compute_record_mode (CLASSTYPE_AS_BASE (t));
|
||||
|
||||
/* Make sure that we get our own copy of the vfield FIELD_DECL. */
|
||||
vfield = TYPE_VFIELD (t);
|
||||
if (vfield && CLASSTYPE_HAS_PRIMARY_BASE_P (t))
|
||||
{
|
||||
tree primary = CLASSTYPE_PRIMARY_BINFO (t);
|
||||
|
||||
gcc_assert (same_type_p (DECL_FIELD_CONTEXT (vfield),
|
||||
BINFO_TYPE (primary)));
|
||||
/* The vtable better be at the start. */
|
||||
gcc_assert (integer_zerop (DECL_FIELD_OFFSET (vfield)));
|
||||
gcc_assert (integer_zerop (BINFO_OFFSET (primary)));
|
||||
|
||||
vfield = copy_decl (vfield);
|
||||
DECL_FIELD_CONTEXT (vfield) = t;
|
||||
TYPE_VFIELD (t) = vfield;
|
||||
}
|
||||
else
|
||||
gcc_assert (!vfield || DECL_FIELD_CONTEXT (vfield) == t);
|
||||
|
||||
virtuals = modify_all_vtables (t, nreverse (virtuals));
|
||||
|
||||
/* If necessary, create the primary vtable for this class. */
|
||||
|
@ -1711,9 +1711,14 @@ build_class_member_access_expr (tree object, tree member,
|
||||
give the right answer. Note that we complain whether or not they
|
||||
actually used the offsetof macro, since there's no way to know at this
|
||||
point. So we just give a warning, instead of a pedwarn. */
|
||||
/* Do not produce this warning for base class field references, because
|
||||
we know for a fact that didn't come from offsetof. This does occur
|
||||
in various testsuite cases where a null object is passed where a
|
||||
vtable access is required. */
|
||||
if (null_object_p && warn_invalid_offsetof
|
||||
&& CLASSTYPE_NON_POD_P (object_type)
|
||||
&& ! skip_evaluation)
|
||||
&& !DECL_FIELD_IS_BASE (member)
|
||||
&& !skip_evaluation)
|
||||
{
|
||||
warning ("invalid access to non-static data member `%D' of NULL object",
|
||||
member);
|
||||
|
Loading…
Reference in New Issue
Block a user