mirror of
https://github.com/golang/go
synced 2024-09-15 22:20:06 +00:00
cmd/5g, cmd/6g, cmd/8g: more nil ptr to large struct checks
R=r, ken, khr, daniel.morsing CC=dsymonds, golang-dev, rickyz https://golang.org/cl/8925043
This commit is contained in:
parent
73417e4098
commit
578dc3a96c
|
@ -679,6 +679,19 @@ agen(Node *n, Node *res)
|
||||||
|
|
||||||
case ODOT:
|
case ODOT:
|
||||||
agen(nl, res);
|
agen(nl, res);
|
||||||
|
// explicit check for nil if struct is large enough
|
||||||
|
// that we might derive too big a pointer.
|
||||||
|
if(nl->type->width >= unmappedzero) {
|
||||||
|
regalloc(&n1, types[tptr], N);
|
||||||
|
gmove(res, &n1);
|
||||||
|
regalloc(&n2, types[TUINT8], &n1);
|
||||||
|
n1.op = OINDREG;
|
||||||
|
n1.type = types[TUINT8];
|
||||||
|
n1.xoffset = 0;
|
||||||
|
gmove(&n1, &n2);
|
||||||
|
regfree(&n1);
|
||||||
|
regfree(&n2);
|
||||||
|
}
|
||||||
if(n->xoffset != 0) {
|
if(n->xoffset != 0) {
|
||||||
nodconst(&n1, types[TINT32], n->xoffset);
|
nodconst(&n1, types[TINT32], n->xoffset);
|
||||||
regalloc(&n2, n1.type, N);
|
regalloc(&n2, n1.type, N);
|
||||||
|
@ -694,20 +707,20 @@ agen(Node *n, Node *res)
|
||||||
|
|
||||||
case ODOTPTR:
|
case ODOTPTR:
|
||||||
cgen(nl, res);
|
cgen(nl, res);
|
||||||
|
// explicit check for nil if struct is large enough
|
||||||
|
// that we might derive too big a pointer.
|
||||||
|
if(nl->type->type->width >= unmappedzero) {
|
||||||
|
regalloc(&n1, types[tptr], N);
|
||||||
|
gmove(res, &n1);
|
||||||
|
regalloc(&n2, types[TUINT8], &n1);
|
||||||
|
n1.op = OINDREG;
|
||||||
|
n1.type = types[TUINT8];
|
||||||
|
n1.xoffset = 0;
|
||||||
|
gmove(&n1, &n2);
|
||||||
|
regfree(&n1);
|
||||||
|
regfree(&n2);
|
||||||
|
}
|
||||||
if(n->xoffset != 0) {
|
if(n->xoffset != 0) {
|
||||||
// explicit check for nil if struct is large enough
|
|
||||||
// that we might derive too big a pointer.
|
|
||||||
if(nl->type->type->width >= unmappedzero) {
|
|
||||||
regalloc(&n1, types[tptr], N);
|
|
||||||
gmove(res, &n1);
|
|
||||||
regalloc(&n2, types[TUINT8], &n1);
|
|
||||||
n1.op = OINDREG;
|
|
||||||
n1.type = types[TUINT8];
|
|
||||||
n1.xoffset = 0;
|
|
||||||
gmove(&n1, &n2);
|
|
||||||
regfree(&n1);
|
|
||||||
regfree(&n2);
|
|
||||||
}
|
|
||||||
nodconst(&n1, types[TINT32], n->xoffset);
|
nodconst(&n1, types[TINT32], n->xoffset);
|
||||||
regalloc(&n2, n1.type, N);
|
regalloc(&n2, n1.type, N);
|
||||||
regalloc(&n3, types[tptr], N);
|
regalloc(&n3, types[tptr], N);
|
||||||
|
@ -777,20 +790,18 @@ igen(Node *n, Node *a, Node *res)
|
||||||
regalloc(a, types[tptr], res);
|
regalloc(a, types[tptr], res);
|
||||||
cgen(n->left, a);
|
cgen(n->left, a);
|
||||||
}
|
}
|
||||||
if(n->xoffset != 0) {
|
// explicit check for nil if struct is large enough
|
||||||
// explicit check for nil if struct is large enough
|
// that we might derive too big a pointer.
|
||||||
// that we might derive too big a pointer.
|
if(n->left->type->type->width >= unmappedzero) {
|
||||||
if(n->left->type->type->width >= unmappedzero) {
|
regalloc(&n1, types[tptr], N);
|
||||||
regalloc(&n1, types[tptr], N);
|
gmove(a, &n1);
|
||||||
gmove(a, &n1);
|
regalloc(&n2, types[TUINT8], &n1);
|
||||||
regalloc(&n2, types[TUINT8], &n1);
|
n1.op = OINDREG;
|
||||||
n1.op = OINDREG;
|
n1.type = types[TUINT8];
|
||||||
n1.type = types[TUINT8];
|
n1.xoffset = 0;
|
||||||
n1.xoffset = 0;
|
gmove(&n1, &n2);
|
||||||
gmove(&n1, &n2);
|
regfree(&n1);
|
||||||
regfree(&n1);
|
regfree(&n2);
|
||||||
regfree(&n2);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
a->op = OINDREG;
|
a->op = OINDREG;
|
||||||
a->xoffset = n->xoffset;
|
a->xoffset = n->xoffset;
|
||||||
|
|
|
@ -882,24 +882,35 @@ agen(Node *n, Node *res)
|
||||||
|
|
||||||
case ODOT:
|
case ODOT:
|
||||||
agen(nl, res);
|
agen(nl, res);
|
||||||
|
// explicit check for nil if struct is large enough
|
||||||
|
// that we might derive too big a pointer.
|
||||||
|
if(nl->type->width >= unmappedzero) {
|
||||||
|
regalloc(&n1, types[tptr], res);
|
||||||
|
gmove(res, &n1);
|
||||||
|
n1.op = OINDREG;
|
||||||
|
n1.type = types[TUINT8];
|
||||||
|
n1.xoffset = 0;
|
||||||
|
gins(ATESTB, nodintconst(0), &n1);
|
||||||
|
regfree(&n1);
|
||||||
|
}
|
||||||
if(n->xoffset != 0)
|
if(n->xoffset != 0)
|
||||||
ginscon(optoas(OADD, types[tptr]), n->xoffset, res);
|
ginscon(optoas(OADD, types[tptr]), n->xoffset, res);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ODOTPTR:
|
case ODOTPTR:
|
||||||
cgen(nl, res);
|
cgen(nl, res);
|
||||||
|
// explicit check for nil if struct is large enough
|
||||||
|
// that we might derive too big a pointer.
|
||||||
|
if(nl->type->type->width >= unmappedzero) {
|
||||||
|
regalloc(&n1, types[tptr], res);
|
||||||
|
gmove(res, &n1);
|
||||||
|
n1.op = OINDREG;
|
||||||
|
n1.type = types[TUINT8];
|
||||||
|
n1.xoffset = 0;
|
||||||
|
gins(ATESTB, nodintconst(0), &n1);
|
||||||
|
regfree(&n1);
|
||||||
|
}
|
||||||
if(n->xoffset != 0) {
|
if(n->xoffset != 0) {
|
||||||
// explicit check for nil if struct is large enough
|
|
||||||
// that we might derive too big a pointer.
|
|
||||||
if(nl->type->type->width >= unmappedzero) {
|
|
||||||
regalloc(&n1, types[tptr], res);
|
|
||||||
gmove(res, &n1);
|
|
||||||
n1.op = OINDREG;
|
|
||||||
n1.type = types[TUINT8];
|
|
||||||
n1.xoffset = 0;
|
|
||||||
gins(ATESTB, nodintconst(0), &n1);
|
|
||||||
regfree(&n1);
|
|
||||||
}
|
|
||||||
ginscon(optoas(OADD, types[tptr]), n->xoffset, res);
|
ginscon(optoas(OADD, types[tptr]), n->xoffset, res);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -950,16 +961,14 @@ igen(Node *n, Node *a, Node *res)
|
||||||
|
|
||||||
case ODOTPTR:
|
case ODOTPTR:
|
||||||
cgenr(n->left, a, res);
|
cgenr(n->left, a, res);
|
||||||
if(n->xoffset != 0) {
|
// explicit check for nil if struct is large enough
|
||||||
// explicit check for nil if struct is large enough
|
// that we might derive too big a pointer.
|
||||||
// that we might derive too big a pointer.
|
if(n->left->type->type->width >= unmappedzero) {
|
||||||
if(n->left->type->type->width >= unmappedzero) {
|
n1 = *a;
|
||||||
n1 = *a;
|
n1.op = OINDREG;
|
||||||
n1.op = OINDREG;
|
n1.type = types[TUINT8];
|
||||||
n1.type = types[TUINT8];
|
n1.xoffset = 0;
|
||||||
n1.xoffset = 0;
|
gins(ATESTB, nodintconst(0), &n1);
|
||||||
gins(ATESTB, nodintconst(0), &n1);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
a->op = OINDREG;
|
a->op = OINDREG;
|
||||||
a->xoffset += n->xoffset;
|
a->xoffset += n->xoffset;
|
||||||
|
|
|
@ -739,6 +739,17 @@ agen(Node *n, Node *res)
|
||||||
|
|
||||||
case ODOT:
|
case ODOT:
|
||||||
agen(nl, res);
|
agen(nl, res);
|
||||||
|
// explicit check for nil if struct is large enough
|
||||||
|
// that we might derive too big a pointer.
|
||||||
|
if(nl->type->width >= unmappedzero) {
|
||||||
|
regalloc(&n1, types[tptr], res);
|
||||||
|
gmove(res, &n1);
|
||||||
|
n1.op = OINDREG;
|
||||||
|
n1.type = types[TUINT8];
|
||||||
|
n1.xoffset = 0;
|
||||||
|
gins(ATESTB, nodintconst(0), &n1);
|
||||||
|
regfree(&n1);
|
||||||
|
}
|
||||||
if(n->xoffset != 0) {
|
if(n->xoffset != 0) {
|
||||||
nodconst(&n1, types[tptr], n->xoffset);
|
nodconst(&n1, types[tptr], n->xoffset);
|
||||||
gins(optoas(OADD, types[tptr]), &n1, res);
|
gins(optoas(OADD, types[tptr]), &n1, res);
|
||||||
|
@ -750,18 +761,18 @@ agen(Node *n, Node *res)
|
||||||
if(!isptr[t->etype])
|
if(!isptr[t->etype])
|
||||||
fatal("agen: not ptr %N", n);
|
fatal("agen: not ptr %N", n);
|
||||||
cgen(nl, res);
|
cgen(nl, res);
|
||||||
|
// explicit check for nil if struct is large enough
|
||||||
|
// that we might derive too big a pointer.
|
||||||
|
if(nl->type->type->width >= unmappedzero) {
|
||||||
|
regalloc(&n1, types[tptr], res);
|
||||||
|
gmove(res, &n1);
|
||||||
|
n1.op = OINDREG;
|
||||||
|
n1.type = types[TUINT8];
|
||||||
|
n1.xoffset = 0;
|
||||||
|
gins(ATESTB, nodintconst(0), &n1);
|
||||||
|
regfree(&n1);
|
||||||
|
}
|
||||||
if(n->xoffset != 0) {
|
if(n->xoffset != 0) {
|
||||||
// explicit check for nil if struct is large enough
|
|
||||||
// that we might derive too big a pointer.
|
|
||||||
if(nl->type->type->width >= unmappedzero) {
|
|
||||||
regalloc(&n1, types[tptr], res);
|
|
||||||
gmove(res, &n1);
|
|
||||||
n1.op = OINDREG;
|
|
||||||
n1.type = types[TUINT8];
|
|
||||||
n1.xoffset = 0;
|
|
||||||
gins(ATESTB, nodintconst(0), &n1);
|
|
||||||
regfree(&n1);
|
|
||||||
}
|
|
||||||
nodconst(&n1, types[tptr], n->xoffset);
|
nodconst(&n1, types[tptr], n->xoffset);
|
||||||
gins(optoas(OADD, types[tptr]), &n1, res);
|
gins(optoas(OADD, types[tptr]), &n1, res);
|
||||||
}
|
}
|
||||||
|
@ -825,16 +836,14 @@ igen(Node *n, Node *a, Node *res)
|
||||||
regalloc(a, types[tptr], res);
|
regalloc(a, types[tptr], res);
|
||||||
cgen(n->left, a);
|
cgen(n->left, a);
|
||||||
}
|
}
|
||||||
if(n->xoffset != 0) {
|
// explicit check for nil if struct is large enough
|
||||||
// explicit check for nil if struct is large enough
|
// that we might derive too big a pointer.
|
||||||
// that we might derive too big a pointer.
|
if(n->left->type->type->width >= unmappedzero) {
|
||||||
if(n->left->type->type->width >= unmappedzero) {
|
n1 = *a;
|
||||||
n1 = *a;
|
n1.op = OINDREG;
|
||||||
n1.op = OINDREG;
|
n1.type = types[TUINT8];
|
||||||
n1.type = types[TUINT8];
|
n1.xoffset = 0;
|
||||||
n1.xoffset = 0;
|
gins(ATESTB, nodintconst(0), &n1);
|
||||||
gins(ATESTB, nodintconst(0), &n1);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
a->op = OINDREG;
|
a->op = OINDREG;
|
||||||
a->xoffset += n->xoffset;
|
a->xoffset += n->xoffset;
|
||||||
|
|
|
@ -38,6 +38,8 @@ func main() {
|
||||||
shouldPanic(p8)
|
shouldPanic(p8)
|
||||||
shouldPanic(p9)
|
shouldPanic(p9)
|
||||||
shouldPanic(p10)
|
shouldPanic(p10)
|
||||||
|
shouldPanic(p11)
|
||||||
|
shouldPanic(p12)
|
||||||
}
|
}
|
||||||
|
|
||||||
func shouldPanic(f func()) {
|
func shouldPanic(f func()) {
|
||||||
|
@ -130,3 +132,23 @@ func p10() {
|
||||||
var t *T
|
var t *T
|
||||||
println(t.i) // should crash
|
println(t.i) // should crash
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type T1 struct {
|
||||||
|
T
|
||||||
|
}
|
||||||
|
|
||||||
|
type T2 struct {
|
||||||
|
*T1
|
||||||
|
}
|
||||||
|
|
||||||
|
func p11() {
|
||||||
|
t := &T2{}
|
||||||
|
p := &t.i
|
||||||
|
println(*p)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ADDR(DOT(IND(p))) needs a check also
|
||||||
|
func p12() {
|
||||||
|
var p *T = nil
|
||||||
|
println(*(&((*p).i)))
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue