mirror of
https://github.com/golang/go
synced 2024-11-25 01:08:02 -07:00
gc: work around goto bug
R=ken2 CC=golang-dev https://golang.org/cl/4629042
This commit is contained in:
parent
f011bd378f
commit
5d9dbe19a7
@ -124,6 +124,64 @@ newplist(void)
|
|||||||
return pl;
|
return pl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
clearstk(void)
|
||||||
|
{
|
||||||
|
Plist *pl;
|
||||||
|
Prog *p, *p1, *p2, *p3;
|
||||||
|
Node dst, end, zero, con;
|
||||||
|
|
||||||
|
if(plast->firstpc->to.offset <= 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// reestablish context for inserting code
|
||||||
|
// at beginning of function.
|
||||||
|
pl = plast;
|
||||||
|
p1 = pl->firstpc;
|
||||||
|
p2 = p1->link;
|
||||||
|
pc = mal(sizeof(*pc));
|
||||||
|
clearp(pc);
|
||||||
|
p1->link = pc;
|
||||||
|
|
||||||
|
// zero stack frame
|
||||||
|
|
||||||
|
// MOVW $4(SP), R1
|
||||||
|
nodreg(&dst, types[tptr], 1);
|
||||||
|
p = gins(AMOVW, N, &dst);
|
||||||
|
p->from.type = D_CONST;
|
||||||
|
p->from.reg = REGSP;
|
||||||
|
p->from.offset = 4;
|
||||||
|
|
||||||
|
// MOVW $n(R1), R2
|
||||||
|
nodreg(&end, types[tptr], 2);
|
||||||
|
p = gins(AMOVW, N, &end);
|
||||||
|
p->from.type = D_CONST;
|
||||||
|
p->from.reg = 1;
|
||||||
|
p->from.offset = p1->to.offset;
|
||||||
|
|
||||||
|
// MOVW $0, R3
|
||||||
|
nodreg(&zero, types[TUINT32], 3);
|
||||||
|
nodconst(&con, types[TUINT32], 0);
|
||||||
|
gmove(&con, &zero);
|
||||||
|
|
||||||
|
// L:
|
||||||
|
// MOVW.P R3, 0(R1) +4
|
||||||
|
// CMP R1, R2
|
||||||
|
// BNE L
|
||||||
|
p = gins(AMOVW, &zero, &dst);
|
||||||
|
p->to.type = D_OREG;
|
||||||
|
p->to.offset = 4;
|
||||||
|
p->scond |= C_PBIT;
|
||||||
|
p3 = p;
|
||||||
|
p = gins(ACMP, &dst, N);
|
||||||
|
raddr(&end, p);
|
||||||
|
patch(gbranch(ABNE, T), p3);
|
||||||
|
|
||||||
|
// continue with original code.
|
||||||
|
gins(ANOP, N, N)->link = p2;
|
||||||
|
pc = P;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
gused(Node *n)
|
gused(Node *n)
|
||||||
{
|
{
|
||||||
|
@ -120,6 +120,41 @@ newplist(void)
|
|||||||
return pl;
|
return pl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
clearstk(void)
|
||||||
|
{
|
||||||
|
Plist *pl;
|
||||||
|
Prog *p1, *p2;
|
||||||
|
Node sp, di, cx, con;
|
||||||
|
|
||||||
|
if((uint32)plast->firstpc->to.offset <= 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// reestablish context for inserting code
|
||||||
|
// at beginning of function.
|
||||||
|
pl = plast;
|
||||||
|
p1 = pl->firstpc;
|
||||||
|
p2 = p1->link;
|
||||||
|
pc = mal(sizeof(*pc));
|
||||||
|
clearp(pc);
|
||||||
|
p1->link = pc;
|
||||||
|
|
||||||
|
// zero stack frame
|
||||||
|
nodreg(&sp, types[tptr], D_SP);
|
||||||
|
nodreg(&di, types[tptr], D_DI);
|
||||||
|
nodreg(&cx, types[TUINT64], D_CX);
|
||||||
|
nodconst(&con, types[TUINT64], (uint32)p1->to.offset / widthptr);
|
||||||
|
gins(ACLD, N, N);
|
||||||
|
gins(AMOVQ, &sp, &di);
|
||||||
|
gins(AMOVQ, &con, &cx);
|
||||||
|
gins(AREP, N, N);
|
||||||
|
gins(ASTOSQ, N, N);
|
||||||
|
|
||||||
|
// continue with original code.
|
||||||
|
gins(ANOP, N, N)->link = p2;
|
||||||
|
pc = P;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
gused(Node *n)
|
gused(Node *n)
|
||||||
{
|
{
|
||||||
|
@ -122,6 +122,41 @@ newplist(void)
|
|||||||
return pl;
|
return pl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
clearstk(void)
|
||||||
|
{
|
||||||
|
Plist *pl;
|
||||||
|
Prog *p1, *p2;
|
||||||
|
Node sp, di, cx, con;
|
||||||
|
|
||||||
|
if(plast->firstpc->to.offset <= 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// reestablish context for inserting code
|
||||||
|
// at beginning of function.
|
||||||
|
pl = plast;
|
||||||
|
p1 = pl->firstpc;
|
||||||
|
p2 = p1->link;
|
||||||
|
pc = mal(sizeof(*pc));
|
||||||
|
clearp(pc);
|
||||||
|
p1->link = pc;
|
||||||
|
|
||||||
|
// zero stack frame
|
||||||
|
nodreg(&sp, types[tptr], D_SP);
|
||||||
|
nodreg(&di, types[tptr], D_DI);
|
||||||
|
nodreg(&cx, types[TUINT32], D_CX);
|
||||||
|
nodconst(&con, types[TUINT32], p1->to.offset / widthptr);
|
||||||
|
gins(ACLD, N, N);
|
||||||
|
gins(AMOVL, &sp, &di);
|
||||||
|
gins(AMOVL, &con, &cx);
|
||||||
|
gins(AREP, N, N);
|
||||||
|
gins(ASTOSL, N, N);
|
||||||
|
|
||||||
|
// continue with original code.
|
||||||
|
gins(ANOP, N, N)->link = p2;
|
||||||
|
pc = P;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
gused(Node *n)
|
gused(Node *n)
|
||||||
{
|
{
|
||||||
|
@ -1241,9 +1241,14 @@ funccompile(Node *n, int isclosure)
|
|||||||
stksize = 0;
|
stksize = 0;
|
||||||
dclcontext = PAUTO;
|
dclcontext = PAUTO;
|
||||||
funcdepth = n->funcdepth + 1;
|
funcdepth = n->funcdepth + 1;
|
||||||
|
hasgoto = 0;
|
||||||
compile(n);
|
compile(n);
|
||||||
|
if(hasgoto)
|
||||||
|
clearstk();
|
||||||
curfn = nil;
|
curfn = nil;
|
||||||
funcdepth = 0;
|
funcdepth = 0;
|
||||||
dclcontext = PEXTERN;
|
dclcontext = PEXTERN;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -209,6 +209,7 @@ gen(Node *n)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case OGOTO:
|
case OGOTO:
|
||||||
|
hasgoto = 1;
|
||||||
newlab(OGOTO, n, N);
|
newlab(OGOTO, n, N);
|
||||||
gjmp(P);
|
gjmp(P);
|
||||||
break;
|
break;
|
||||||
|
@ -1257,3 +1257,6 @@ void zhist(Biobuf *b, int line, vlong offset);
|
|||||||
void zname(Biobuf *b, Sym *s, int t);
|
void zname(Biobuf *b, Sym *s, int t);
|
||||||
void data(void);
|
void data(void);
|
||||||
void text(void);
|
void text(void);
|
||||||
|
|
||||||
|
EXTERN int hasgoto;
|
||||||
|
void clearstk(void);
|
||||||
|
22
test/fixedbugs/bug344.go
Normal file
22
test/fixedbugs/bug344.go
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
// $G $D/$F.go && $L $F.$A && ./$A.out || echo BUG: bug344
|
||||||
|
|
||||||
|
// Copyright 2011 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.
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import "fmt"
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
// invalid use of goto.
|
||||||
|
// do whatever you like, just don't crash.
|
||||||
|
i := 42
|
||||||
|
a := []*int{&i, &i, &i, &i}
|
||||||
|
x := a[0]
|
||||||
|
goto start
|
||||||
|
for _, x = range a {
|
||||||
|
start:
|
||||||
|
fmt.Sprint(*x)
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user