From 51b08adabf40a7922771ff4e0c36c8680c082825 Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Fri, 14 Jun 2013 17:59:48 +0000 Subject: compiler: fix computation of Offsetof. The implied offsets must be taken into account when the selector involves anonymous fields. From-SVN: r200098 --- gcc/go/gofrontend/expressions.cc | 36 ++++++++++++++++++++++++------------ 1 file changed, 24 insertions(+), 12 deletions(-) (limited to 'gcc/go/gofrontend/expressions.cc') diff --git a/gcc/go/gofrontend/expressions.cc b/gcc/go/gofrontend/expressions.cc index 9abd224..afc1832 100644 --- a/gcc/go/gofrontend/expressions.cc +++ b/gcc/go/gofrontend/expressions.cc @@ -7279,19 +7279,31 @@ Builtin_call_expression::do_numeric_constant_value(Numeric_constant* nc) const Field_reference_expression* farg = arg->field_reference_expression(); if (farg == NULL) return false; - Expression* struct_expr = farg->expr(); - Type* st = struct_expr->type(); - if (st->struct_type() == NULL) - return false; - if (st->named_type() != NULL) - st->named_type()->convert(this->gogo_); - unsigned int offset; - if (!st->struct_type()->backend_field_offset(this->gogo_, - farg->field_index(), - &offset)) - return false; + unsigned int total_offset = 0; + while (true) + { + Expression* struct_expr = farg->expr(); + Type* st = struct_expr->type(); + if (st->struct_type() == NULL) + return false; + if (st->named_type() != NULL) + st->named_type()->convert(this->gogo_); + unsigned int offset; + if (!st->struct_type()->backend_field_offset(this->gogo_, + farg->field_index(), + &offset)) + return false; + total_offset += offset; + if (farg->implicit() && struct_expr->field_reference_expression() != NULL) + { + // Go up until we reach the original base. + farg = struct_expr->field_reference_expression(); + continue; + } + break; + } nc->set_unsigned_long(Type::lookup_integer_type("uintptr"), - static_cast(offset)); + static_cast(total_offset)); return true; } else if (this->code_ == BUILTIN_REAL || this->code_ == BUILTIN_IMAG) -- cgit v1.1