In Go it is not valid to use unsafe.Offsetof with a reference to an embedded field that is accessed via an embedded pointer, because there is no reasonable answer to return in that case. Unfortunately gccgo was returning bogus results for that case. This patch from Rémy Oudompheng fixes it to return an error. There is a test case in the master testsuite that will be imported into gccgo in due course. Bootstrapped and ran Go testsuite on x86_64-unknown-linux-gnu. Committed to mainline and 4.8 branch.
Ian
diff -r 3d794090fa86 go/expressions.cc --- a/go/expressions.cc Tue Jun 18 16:01:29 2013 -0700 +++ b/go/expressions.cc Wed Jun 19 14:16:32 2013 -0700 @@ -6955,6 +6955,26 @@ return Expression::make_error(loc); } + if (this->code_ == BUILTIN_OFFSETOF) + { + Expression* arg = this->one_arg(); + Field_reference_expression* farg = arg->field_reference_expression(); + while (farg != NULL) + { + if (!farg->implicit()) + break; + // When the selector refers to an embedded field, + // it must not be reached through pointer indirections. + if (farg->expr()->deref() != farg->expr()) + { + this->report_error(_("argument of Offsetof implies indirection of an embedded field")); + return this; + } + // Go up until we reach the original base. + farg = farg->expr()->field_reference_expression(); + } + } + if (this->is_constant()) { Numeric_constant nc; diff -r 3d794090fa86 go/expressions.h --- a/go/expressions.h Tue Jun 18 16:01:29 2013 -0700 +++ b/go/expressions.h Wed Jun 19 14:16:32 2013 -0700 @@ -1872,7 +1872,7 @@ Field_reference_expression(Expression* expr, unsigned int field_index, Location location) : Expression(EXPRESSION_FIELD_REFERENCE, location), - expr_(expr), field_index_(field_index), called_fieldtrack_(false) + expr_(expr), field_index_(field_index), implicit_(false), called_fieldtrack_(false) { } // Return the struct expression.