diff options
author | Russ Cox <rsc@golang.org> | 2011-07-28 16:28:23 -0400 |
---|---|---|
committer | Russ Cox <rsc@golang.org> | 2011-07-28 16:28:23 -0400 |
commit | 8c23c1ab8797e0b8270d618b0a107d19b8f9faa0 (patch) | |
tree | 51ec24b1eb98e2da49790bf0c29d751eead3c5a5 | |
parent | 3de6228aea10f6229c9999e440fe9e9dc21435d6 (diff) | |
download | go-8c23c1ab8797e0b8270d618b0a107d19b8f9faa0.tar.gz go-8c23c1ab8797e0b8270d618b0a107d19b8f9faa0.zip |
5g: defer vs optimizer bug
Fixes #1924.
R=ken2
CC=golang-dev
https://golang.org/cl/4802063
-rw-r--r-- | src/cmd/5g/reg.c | 8 | ||||
-rw-r--r-- | test/fixedbugs/bug364.go | 25 |
2 files changed, 32 insertions, 1 deletions
diff --git a/src/cmd/5g/reg.c b/src/cmd/5g/reg.c index 77d0a87eb5..7bb33b7c25 100644 --- a/src/cmd/5g/reg.c +++ b/src/cmd/5g/reg.c @@ -728,13 +728,19 @@ addsplits(void) void addmove(Reg *r, int bn, int rn, int f) { - Prog *p, *p1; + Prog *p, *p1, *p2; Adr *a; Var *v; p1 = mal(sizeof(*p1)); *p1 = zprog; p = r->prog; + + // If there's a stack fixup coming (after BL newproc or BL deferproc), + // delay the load until after the fixup. + p2 = p->link; + if(p2 && p2->as == AMOVW && p2->from.type == D_CONST && p2->from.reg == REGSP && p2->to.reg == REGSP && p2->to.type == D_REG) + p = p2; p1->link = p->link; p->link = p1; diff --git a/test/fixedbugs/bug364.go b/test/fixedbugs/bug364.go new file mode 100644 index 0000000000..a174534194 --- /dev/null +++ b/test/fixedbugs/bug364.go @@ -0,0 +1,25 @@ +package main + +import "fmt" + +var s string + +func accum(args ...interface{}) { + s += fmt.Sprintln(args...) +} + +func f(){ + v := 0.0 + for i := 0; i < 3; i++ { + v += 0.1 + defer accum(v) + } +} + +func main() { + f() + if s != "0.30000000000000004\n0.2\n0.1\n" { + println("BUG: defer") + print(s) + } +} |