mirror of
https://github.com/golang/go
synced 2024-11-02 09:28:34 +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
4 changed files with 120 additions and 69 deletions
|
@ -679,6 +679,19 @@ agen(Node *n, Node *res)
|
|||
|
||||
case ODOT:
|
||||
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) {
|
||||
nodconst(&n1, types[TINT32], n->xoffset);
|
||||
regalloc(&n2, n1.type, N);
|
||||
|
@ -694,7 +707,6 @@ agen(Node *n, Node *res)
|
|||
|
||||
case ODOTPTR:
|
||||
cgen(nl, res);
|
||||
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) {
|
||||
|
@ -708,6 +720,7 @@ agen(Node *n, Node *res)
|
|||
regfree(&n1);
|
||||
regfree(&n2);
|
||||
}
|
||||
if(n->xoffset != 0) {
|
||||
nodconst(&n1, types[TINT32], n->xoffset);
|
||||
regalloc(&n2, n1.type, N);
|
||||
regalloc(&n3, types[tptr], N);
|
||||
|
@ -777,7 +790,6 @@ igen(Node *n, Node *a, Node *res)
|
|||
regalloc(a, types[tptr], res);
|
||||
cgen(n->left, a);
|
||||
}
|
||||
if(n->xoffset != 0) {
|
||||
// explicit check for nil if struct is large enough
|
||||
// that we might derive too big a pointer.
|
||||
if(n->left->type->type->width >= unmappedzero) {
|
||||
|
@ -791,7 +803,6 @@ igen(Node *n, Node *a, Node *res)
|
|||
regfree(&n1);
|
||||
regfree(&n2);
|
||||
}
|
||||
}
|
||||
a->op = OINDREG;
|
||||
a->xoffset = n->xoffset;
|
||||
a->type = n->type;
|
||||
|
|
|
@ -882,13 +882,23 @@ agen(Node *n, Node *res)
|
|||
|
||||
case ODOT:
|
||||
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)
|
||||
ginscon(optoas(OADD, types[tptr]), n->xoffset, res);
|
||||
break;
|
||||
|
||||
case ODOTPTR:
|
||||
cgen(nl, res);
|
||||
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) {
|
||||
|
@ -900,6 +910,7 @@ agen(Node *n, Node *res)
|
|||
gins(ATESTB, nodintconst(0), &n1);
|
||||
regfree(&n1);
|
||||
}
|
||||
if(n->xoffset != 0) {
|
||||
ginscon(optoas(OADD, types[tptr]), n->xoffset, res);
|
||||
}
|
||||
break;
|
||||
|
@ -950,7 +961,6 @@ igen(Node *n, Node *a, Node *res)
|
|||
|
||||
case ODOTPTR:
|
||||
cgenr(n->left, a, res);
|
||||
if(n->xoffset != 0) {
|
||||
// explicit check for nil if struct is large enough
|
||||
// that we might derive too big a pointer.
|
||||
if(n->left->type->type->width >= unmappedzero) {
|
||||
|
@ -960,7 +970,6 @@ igen(Node *n, Node *a, Node *res)
|
|||
n1.xoffset = 0;
|
||||
gins(ATESTB, nodintconst(0), &n1);
|
||||
}
|
||||
}
|
||||
a->op = OINDREG;
|
||||
a->xoffset += n->xoffset;
|
||||
a->type = n->type;
|
||||
|
|
|
@ -739,6 +739,17 @@ agen(Node *n, Node *res)
|
|||
|
||||
case ODOT:
|
||||
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) {
|
||||
nodconst(&n1, types[tptr], n->xoffset);
|
||||
gins(optoas(OADD, types[tptr]), &n1, res);
|
||||
|
@ -750,7 +761,6 @@ agen(Node *n, Node *res)
|
|||
if(!isptr[t->etype])
|
||||
fatal("agen: not ptr %N", n);
|
||||
cgen(nl, res);
|
||||
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) {
|
||||
|
@ -762,6 +772,7 @@ agen(Node *n, Node *res)
|
|||
gins(ATESTB, nodintconst(0), &n1);
|
||||
regfree(&n1);
|
||||
}
|
||||
if(n->xoffset != 0) {
|
||||
nodconst(&n1, types[tptr], n->xoffset);
|
||||
gins(optoas(OADD, types[tptr]), &n1, res);
|
||||
}
|
||||
|
@ -825,7 +836,6 @@ igen(Node *n, Node *a, Node *res)
|
|||
regalloc(a, types[tptr], res);
|
||||
cgen(n->left, a);
|
||||
}
|
||||
if(n->xoffset != 0) {
|
||||
// explicit check for nil if struct is large enough
|
||||
// that we might derive too big a pointer.
|
||||
if(n->left->type->type->width >= unmappedzero) {
|
||||
|
@ -835,7 +845,6 @@ igen(Node *n, Node *a, Node *res)
|
|||
n1.xoffset = 0;
|
||||
gins(ATESTB, nodintconst(0), &n1);
|
||||
}
|
||||
}
|
||||
a->op = OINDREG;
|
||||
a->xoffset += n->xoffset;
|
||||
a->type = n->type;
|
||||
|
|
|
@ -38,6 +38,8 @@ func main() {
|
|||
shouldPanic(p8)
|
||||
shouldPanic(p9)
|
||||
shouldPanic(p10)
|
||||
shouldPanic(p11)
|
||||
shouldPanic(p12)
|
||||
}
|
||||
|
||||
func shouldPanic(f func()) {
|
||||
|
@ -130,3 +132,23 @@ func p10() {
|
|||
var t *T
|
||||
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