Commit f2d9afec by Jason Merrill Committed by Jason Merrill

typeck.c (build_component_ref): Always complain about offsetof constructs on non-PODs.

        * typeck.c (build_component_ref): Always complain about offsetof
        constructs on non-PODs.  Only make it an error for members of
        virtual bases.

From-SVN: r49406
parent 1338ea6c
2002-02-01 Jason Merrill <jason@redhat.com>
* typeck.c (build_component_ref): Always complain about offsetof
constructs on non-PODs. Only make it an error for members of
virtual bases.
* error.c (dump_scope): Don't add TFF_DECL_SPECIFIERS.
(dump_function_decl): Always dump parms.
......
......@@ -1999,6 +1999,8 @@ build_component_ref (datum, component, basetype_path, protect)
register tree ref;
tree field_type;
int type_quals;
tree old_datum;
tree old_basetype;
if (processing_template_decl)
return build_min_nt (COMPONENT_REF, datum, component);
......@@ -2202,6 +2204,9 @@ build_component_ref (datum, component, basetype_path, protect)
if (TREE_DEPRECATED (field))
warn_deprecated_use (field);
old_datum = datum;
old_basetype = basetype;
/* See if we have to do any conversions so that we pick up the field from the
right context. */
if (DECL_FIELD_CONTEXT (field) != basetype)
......@@ -2215,12 +2220,17 @@ build_component_ref (datum, component, basetype_path, protect)
/* Handle base classes here... */
if (base != basetype && TYPE_BASE_CONVS_MAY_REQUIRE_CODE_P (basetype))
{
tree binfo = lookup_base (TREE_TYPE (datum), base, ba_check, NULL);
base_kind kind;
tree binfo = lookup_base (TREE_TYPE (datum), base, ba_check, &kind);
/* Complain about use of offsetof which will break. */
if (TREE_CODE (datum) == INDIRECT_REF
&& integer_zerop (TREE_OPERAND (datum, 0)))
&& integer_zerop (TREE_OPERAND (datum, 0))
&& kind == bk_via_virtual)
{
error ("invalid reference to NULL ptr, use ptr-to-member instead");
error ("\
invalid offsetof from non-POD type `%#T'; use pointer to member instead",
basetype);
return error_mark_node;
}
datum = build_base_path (PLUS_EXPR, datum, binfo, 1);
......@@ -2239,6 +2249,18 @@ build_component_ref (datum, component, basetype_path, protect)
}
}
/* Complain about other invalid uses of offsetof, even though they will
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. */
if (protect
&& CLASSTYPE_NON_POD_P (old_basetype)
&& TREE_CODE (old_datum) == INDIRECT_REF
&& integer_zerop (TREE_OPERAND (old_datum, 0)))
warning ("\
invalid offsetof from non-POD type `%#T'; use pointer to member instead",
basetype);
/* Compute the type of the field, as described in [expr.ref]. */
type_quals = TYPE_UNQUALIFIED;
field_type = TREE_TYPE (field);
......
// Test that we can refer to the address of a base member of a null pointer
// to get its offset. The standard says that offsetof shall not be used on
// non-POD classes, but there seems to be no such restriction on the common
// implementation thereof.
// Yes, this is bad, naughty, evil code. But it seems to be well-formed.
// So we'll just warn.
// { dg-do run }
struct A { int i; };
struct B: public A {
virtual void f ();
};
struct C: public B { };
int main ()
{
return ((unsigned long) &((C*)0)->i) != 4; // { dg-warning "offsetof" "" }
}
......@@ -46,10 +46,13 @@ struct R {
X<&B::j> x;
};
B b;
D d;
void f()
{
((B*)0)->i = 3; // ERROR - protected
((D*)0)->i = 4;
b.i = 3; // ERROR - protected
d.i = 4;
B::j = 5;
D::j = 6;
}
......@@ -57,8 +60,8 @@ void f()
template <typename T>
void g()
{
((B*)0)->i = 3; // ERROR - protected
((D*)0)->i = 4;
b.i = 3; // ERROR - protected
d.i = 4;
B::j = 5;
D::j = 6;
}
......@@ -67,8 +70,8 @@ template void g<int>();
void S::h()
{
((B*)0)->i = 3; // ERROR - protected
((D*)0)->i = 4;
b.i = 3; // ERROR - protected
d.i = 4;
B::j = 5;
D::j = 6;
}
......@@ -76,8 +79,8 @@ void S::h()
template <typename T>
void R<T>::h()
{
((B*)0)->i = 3; // ERROR - protected
((D*)0)->i = 4;
b.i = 3; // ERROR - protected
d.i = 4;
B::j = 5;
D::j = 6;
}
......
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