mirror of
https://github.com/golang/go
synced 2024-11-22 00:34:40 -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
|
* unsafe.c
|
||||||
*/
|
*/
|
||||||
Node* unsafenmagic(Node *fn, NodeList *args);
|
Node* unsafenmagic(Node *n);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* walk.c
|
* walk.c
|
||||||
|
@ -267,6 +267,7 @@ exprfmt(Fmt *f, Node *n, int prec)
|
|||||||
fmtprint(f, "struct literal");
|
fmtprint(f, "struct literal");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case OXDOT:
|
||||||
case ODOT:
|
case ODOT:
|
||||||
case ODOTPTR:
|
case ODOTPTR:
|
||||||
case ODOTINTER:
|
case ODOTINTER:
|
||||||
|
@ -690,7 +690,7 @@ reswitch:
|
|||||||
*/
|
*/
|
||||||
case OCALL:
|
case OCALL:
|
||||||
l = n->left;
|
l = n->left;
|
||||||
if(l->op == ONAME && (r = unsafenmagic(l, n->list)) != N) {
|
if(l->op == ONAME && (r = unsafenmagic(n)) != N) {
|
||||||
n = r;
|
n = r;
|
||||||
goto reswitch;
|
goto reswitch;
|
||||||
}
|
}
|
||||||
|
@ -11,13 +11,18 @@
|
|||||||
* rewrite with a constant
|
* rewrite with a constant
|
||||||
*/
|
*/
|
||||||
Node*
|
Node*
|
||||||
unsafenmagic(Node *fn, NodeList *args)
|
unsafenmagic(Node *nn)
|
||||||
{
|
{
|
||||||
Node *r, *n;
|
Node *r, *n;
|
||||||
Sym *s;
|
Sym *s;
|
||||||
Type *t, *tr;
|
Type *t, *tr;
|
||||||
long v;
|
long v;
|
||||||
Val val;
|
Val val;
|
||||||
|
Node *fn;
|
||||||
|
NodeList *args;
|
||||||
|
|
||||||
|
fn = nn->left;
|
||||||
|
args = nn->list;
|
||||||
|
|
||||||
if(safemode || fn == N || fn->op != ONAME || (s = fn->sym) == S)
|
if(safemode || fn == N || fn->op != ONAME || (s = fn->sym) == S)
|
||||||
goto no;
|
goto no;
|
||||||
@ -35,13 +40,14 @@ unsafenmagic(Node *fn, NodeList *args)
|
|||||||
defaultlit(&r, T);
|
defaultlit(&r, T);
|
||||||
tr = r->type;
|
tr = r->type;
|
||||||
if(tr == T)
|
if(tr == T)
|
||||||
goto no;
|
goto bad;
|
||||||
v = tr->width;
|
v = tr->width;
|
||||||
goto yes;
|
goto yes;
|
||||||
}
|
}
|
||||||
if(strcmp(s->name, "Offsetof") == 0) {
|
if(strcmp(s->name, "Offsetof") == 0) {
|
||||||
|
typecheck(&r, Erv);
|
||||||
if(r->op != ODOT && r->op != ODOTPTR)
|
if(r->op != ODOT && r->op != ODOTPTR)
|
||||||
goto no;
|
goto bad;
|
||||||
typecheck(&r, Erv);
|
typecheck(&r, Erv);
|
||||||
v = r->xoffset;
|
v = r->xoffset;
|
||||||
goto yes;
|
goto yes;
|
||||||
@ -51,7 +57,7 @@ unsafenmagic(Node *fn, NodeList *args)
|
|||||||
defaultlit(&r, T);
|
defaultlit(&r, T);
|
||||||
tr = r->type;
|
tr = r->type;
|
||||||
if(tr == T)
|
if(tr == T)
|
||||||
goto no;
|
goto bad;
|
||||||
|
|
||||||
// make struct { byte; T; }
|
// make struct { byte; T; }
|
||||||
t = typ(TSTRUCT);
|
t = typ(TSTRUCT);
|
||||||
@ -70,9 +76,15 @@ unsafenmagic(Node *fn, NodeList *args)
|
|||||||
no:
|
no:
|
||||||
return N;
|
return N;
|
||||||
|
|
||||||
|
bad:
|
||||||
|
yyerror("invalid expression %#N", nn);
|
||||||
|
v = 0;
|
||||||
|
goto ret;
|
||||||
|
|
||||||
yes:
|
yes:
|
||||||
if(args->next != nil)
|
if(args->next != nil)
|
||||||
yyerror("extra arguments for %S", s);
|
yyerror("extra arguments for %S", s);
|
||||||
|
ret:
|
||||||
// any side effects disappear; ignore init
|
// any side effects disappear; ignore init
|
||||||
val.ctype = CTINT;
|
val.ctype = CTINT;
|
||||||
val.u.xval = mal(sizeof(*n->val.u.xval));
|
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