From: jason Date: Fri, 1 Feb 2002 19:31:23 +0000 (+0000) Subject: * typeck.c (build_component_ref): Always complain about offsetof X-Git-Tag: upstream/4.9.2~88982 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=33d31608efaff0bcd06e6ee67a70fc46bbebf974;p=platform%2Fupstream%2Flinaro-gcc.git * typeck.c (build_component_ref): Always complain about offsetof constructs on non-PODs. Only make it an error for members of virtual bases. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@49406 138bc75d-0d04-0410-961f-82ee72b054a4 --- diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 63c8747..af18329 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,9 @@ 2002-02-01 Jason Merrill + * 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. diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index 5e69b98..ba37b10 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -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); diff --git a/gcc/testsuite/g++.dg/abi/offsetof.C b/gcc/testsuite/g++.dg/abi/offsetof.C new file mode 100644 index 0000000..8a2e732 --- /dev/null +++ b/gcc/testsuite/g++.dg/abi/offsetof.C @@ -0,0 +1,22 @@ +// 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" "" } +} diff --git a/gcc/testsuite/g++.old-deja/g++.other/friend1.C b/gcc/testsuite/g++.old-deja/g++.other/friend1.C index 76fcebe..f8e22c2 100644 --- a/gcc/testsuite/g++.old-deja/g++.other/friend1.C +++ b/gcc/testsuite/g++.old-deja/g++.other/friend1.C @@ -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 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(); 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 void R::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; }