Skip to content

Commit

Permalink
gc: bug292
Browse files Browse the repository at this point in the history
Fixes #843.

R=ken2
CC=golang-dev
https://golang.org/cl/1729051
  • Loading branch information
rsc committed Jul 15, 2010
1 parent 496a935 commit cdb446f
Show file tree
Hide file tree
Showing 5 changed files with 41 additions and 6 deletions.
2 changes: 1 addition & 1 deletion src/cmd/gc/go.h
Expand Up @@ -1145,7 +1145,7 @@ void typechecklist(NodeList *l, int top);
/*
* unsafe.c
*/
Node* unsafenmagic(Node *fn, NodeList *args);
Node* unsafenmagic(Node *n);

/*
* walk.c
Expand Down
1 change: 1 addition & 0 deletions src/cmd/gc/print.c
Expand Up @@ -267,6 +267,7 @@ exprfmt(Fmt *f, Node *n, int prec)
fmtprint(f, "struct literal");
break;

case OXDOT:
case ODOT:
case ODOTPTR:
case ODOTINTER:
Expand Down
2 changes: 1 addition & 1 deletion src/cmd/gc/typecheck.c
Expand Up @@ -690,7 +690,7 @@ typecheck(Node **np, int top)
*/
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;
}
Expand Down
20 changes: 16 additions & 4 deletions src/cmd/gc/unsafe.c
Expand Up @@ -11,13 +11,18 @@
* 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;
Expand All @@ -35,13 +40,14 @@ unsafenmagic(Node *fn, NodeList *args)
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;
Expand All @@ -51,7 +57,7 @@ unsafenmagic(Node *fn, NodeList *args)
defaultlit(&r, T);
tr = r->type;
if(tr == T)
goto no;
goto bad;

// make struct { byte; T; }
t = typ(TSTRUCT);
Expand All @@ -70,9 +76,15 @@ unsafenmagic(Node *fn, NodeList *args)
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));
Expand Down
22 changes: 22 additions & 0 deletions test/fixedbugs/bug292.go
@@ -0,0 +1,22 @@
// $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))
}
}

0 comments on commit cdb446f

Please sign in to comment.