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.

Reply via email to