mirror of
https://github.com/golang/go
synced 2024-11-11 22:50:22 -07:00
gc: bug292
Fixes #843. R=ken2 CC=golang-dev https://golang.org/cl/1729051
This commit is contained in:
parent
496a935376
commit
cdb446feb5
@ -1145,7 +1145,7 @@ void typechecklist(NodeList *l, int top);
|
||||
/*
|
||||
* unsafe.c
|
||||
*/
|
||||
Node* unsafenmagic(Node *fn, NodeList *args);
|
||||
Node* unsafenmagic(Node *n);
|
||||
|
||||
/*
|
||||
* walk.c
|
||||
|
@ -267,6 +267,7 @@ exprfmt(Fmt *f, Node *n, int prec)
|
||||
fmtprint(f, "struct literal");
|
||||
break;
|
||||
|
||||
case OXDOT:
|
||||
case ODOT:
|
||||
case ODOTPTR:
|
||||
case ODOTINTER:
|
||||
|
@ -690,7 +690,7 @@ reswitch:
|
||||
*/
|
||||
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;
|
||||
}
|
||||
|
@ -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;
|
||||
@ -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;
|
||||
@ -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);
|
||||
@ -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));
|
||||
|
22
test/fixedbugs/bug292.go
Normal file
22
test/fixedbugs/bug292.go
Normal file
@ -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))
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user