summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRuss Cox <rsc@golang.org>2012-09-24 15:53:12 -0400
committerRuss Cox <rsc@golang.org>2012-09-24 15:53:12 -0400
commitbd089d90d12aa726961adc6a015502da053127a8 (patch)
treef4358858a3c20b8119ee095e457242e484b84471
parent4f55ef33a1e357fcf825bce7e8ab8fbcb70bd867 (diff)
downloadgo-bd089d90d12aa726961adc6a015502da053127a8.tar.gz
cmd/gc: fix escape analysis bug
Was not handling &x.y[0] and &x.y.z correctly where y is an array or struct-valued field (not a pointer). R=ken2 CC=golang-dev http://codereview.appspot.com/6551059
-rw-r--r--src/cmd/gc/esc.c8
-rw-r--r--test/escape2.go18
-rw-r--r--test/escape4.go18
3 files changed, 43 insertions, 1 deletions
diff --git a/src/cmd/gc/esc.c b/src/cmd/gc/esc.c
index bd197ab23..c5faa041c 100644
--- a/src/cmd/gc/esc.c
+++ b/src/cmd/gc/esc.c
@@ -926,9 +926,15 @@ escwalk(EscState *e, int level, Node *dst, Node *src)
}
break;
+ case ODOT:
+ escwalk(e, level, dst, src->left);
+ break;
+
case OINDEX:
- if(isfixedarray(src->type))
+ if(isfixedarray(src->left->type)) {
+ escwalk(e, level, dst, src->left);
break;
+ }
// fall through
case OSLICE:
case ODOTPTR:
diff --git a/test/escape2.go b/test/escape2.go
index 8f48ef7bd..8db12d991 100644
--- a/test/escape2.go
+++ b/test/escape2.go
@@ -1211,3 +1211,21 @@ func foo137() {
}()
}()
}
+
+func foo138() *byte {
+ type T struct {
+ x [1]byte
+ }
+ t := new(T) // ERROR "new.T. escapes to heap"
+ return &t.x[0] // ERROR "&t.x.0. escapes to heap"
+}
+
+func foo139() *byte {
+ type T struct {
+ x struct {
+ y byte
+ }
+ }
+ t := new(T) // ERROR "new.T. escapes to heap"
+ return &t.x.y // ERROR "&t.x.y escapes to heap"
+}
diff --git a/test/escape4.go b/test/escape4.go
index cc3ac78f0..83bc8eb12 100644
--- a/test/escape4.go
+++ b/test/escape4.go
@@ -37,3 +37,21 @@ func f2() {} // ERROR "can inline f2"
// No inline for panic, recover.
func f3() { panic(1) }
func f4() { recover() }
+
+func f5() *byte {
+ type T struct {
+ x [1]byte
+ }
+ t := new(T) // ERROR "new.T. escapes to heap"
+ return &t.x[0] // ERROR "&t.x.0. escapes to heap"
+}
+
+func f6() *byte {
+ type T struct {
+ x struct {
+ y byte
+ }
+ }
+ t := new(T) // ERROR "new.T. escapes to heap"
+ return &t.x.y // ERROR "&t.x.y escapes to heap"
+}