/*
* unsafe.c
*/
-Node* unsafenmagic(Node *fn, NodeList *args);
+Node* unsafenmagic(Node *n);
/*
* walk.c
fmtprint(f, "struct literal");
break;
+ case OXDOT:
case ODOT:
case ODOTPTR:
case ODOTINTER:
*/
case OCALL:
l = n->left;
- if(l->op == ONAME && (r = unsafenmagic(l, n->list)) != N) {
+ if(l->op == ONAME && (r = unsafenmagic(n)) != N) {
n = r;
goto reswitch;
}
* rewrite with a constant
*/
Node*
-unsafenmagic(Node *fn, NodeList *args)
+unsafenmagic(Node *nn)
{
Node *r, *n;
Sym *s;
Type *t, *tr;
long v;
Val val;
+ Node *fn;
+ NodeList *args;
+
+ fn = nn->left;
+ args = nn->list;
if(safemode || fn == N || fn->op != ONAME || (s = fn->sym) == S)
goto no;
defaultlit(&r, T);
tr = r->type;
if(tr == T)
- goto no;
+ goto bad;
v = tr->width;
goto yes;
}
if(strcmp(s->name, "Offsetof") == 0) {
+ typecheck(&r, Erv);
if(r->op != ODOT && r->op != ODOTPTR)
- goto no;
+ goto bad;
typecheck(&r, Erv);
v = r->xoffset;
goto yes;
defaultlit(&r, T);
tr = r->type;
if(tr == T)
- goto no;
+ goto bad;
// make struct { byte; T; }
t = typ(TSTRUCT);
no:
return N;
+bad:
+ yyerror("invalid expression %#N", nn);
+ v = 0;
+ goto ret;
+
yes:
if(args->next != nil)
yyerror("extra arguments for %S", s);
+ret:
// any side effects disappear; ignore init
val.ctype = CTINT;
val.u.xval = mal(sizeof(*n->val.u.xval));
--- /dev/null
+// $G $D/$F.go && $L $F.$A && ./$A.out
+
+// Copyright 2010 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// http://code.google.com/p/go/issues/detail?id=843
+
+package main
+
+import "unsafe"
+
+type T struct {
+ X, Y uint8
+}
+
+func main() {
+ var t T
+ if unsafe.Offsetof(t.X) != 0 || unsafe.Offsetof(t.Y) != 1 {
+ println("BUG", unsafe.Offsetof(t.X), unsafe.Offsetof(t.Y))
+ }
+}