summaryrefslogtreecommitdiff
path: root/test/escape.go
diff options
context:
space:
mode:
authorRuss Cox <rsc@golang.org>2009-01-29 17:38:58 -0800
committerRuss Cox <rsc@golang.org>2009-01-29 17:38:58 -0800
commit82411b9886df9e9b8f2c05b0804432c3141419b3 (patch)
tree346d845fb120717e657f7a2919d374290fe02f81 /test/escape.go
parent4a2c6c1eafc88455ffc4b1867e922e76f3a7782b (diff)
downloadgo-82411b9886df9e9b8f2c05b0804432c3141419b3.tar.gz
if take address of local, move to heap.
heuristic to not print bogus strings. fix one error message format. R=ken OCL=23849 CL=23851
Diffstat (limited to 'test/escape.go')
-rw-r--r--test/escape.go175
1 files changed, 175 insertions, 0 deletions
diff --git a/test/escape.go b/test/escape.go
new file mode 100644
index 000000000..d2534c60d
--- /dev/null
+++ b/test/escape.go
@@ -0,0 +1,175 @@
+// $G $D/$F.go && $L $F.$A && ./$A.out
+
+// Copyright 2009 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
+
+// check for correct heap-moving of escaped variables.
+// it is hard to check for the allocations, but it is easy
+// to check that if you call the function twice at the
+// same stack level, the pointers returned should be
+// different.
+
+var bad = false
+
+var allptr = make([]*int, 0, 100);
+
+func noalias(p, q *int, s string) {
+ n := len(allptr);
+ *p = -(n+1);
+ *q = -(n+2);
+ allptr = allptr[0:n+2];
+ allptr[n] = p;
+ allptr[n+1] = q;
+ n += 2;
+ for i := 0; i < n; i++ {
+ if allptr[i] != nil && *allptr[i] != -(i+1) {
+ println("aliased pointers", -(i+1), *allptr[i], "after", s);
+ allptr[i] = nil;
+ bad = true;
+ }
+ }
+}
+
+func val(p, q *int, v int, s string) {
+ if *p != v {
+ println("wrong value want", v, "got", *p, "after", s);
+ bad = true;
+ }
+ if *q != v+1 {
+ println("wrong value want", v+1, "got", *q, "after", s);
+ bad = true;
+ }
+}
+
+func chk(p, q *int, v int, s string) {
+ val(p, q, v, s);
+ noalias(p, q, s);
+}
+
+func chkalias(p, q *int, v int, s string) {
+ if p != q {
+ println("want aliased pointers but got different after", s);
+ }
+ if *q != v+1 {
+ println("wrong value want", v+1, "got", *q, "after", s);
+ }
+}
+
+func i_escapes(x int) *int {
+ var i int;
+ i = x;
+ return &i;
+}
+
+func j_escapes(x int) *int {
+ var j int = x;
+ j = x;
+ return &j;
+}
+
+func k_escapes(x int) *int {
+ k := x;
+ return &k;
+}
+
+func in_escapes(x int) *int {
+ return &x;
+}
+
+func send(c chan int, x int) {
+ c <- x;
+}
+
+func select_escapes(x int) *int {
+ c := make(chan int);
+ go send(c, x);
+ select {
+ case req := <-c:
+ return &req;
+ }
+ return nil;
+}
+
+func select_escapes1(x int, y int) (*int, *int) {
+ c := make(chan int);
+ var a [2]int;
+ var p [2]*int;
+ a[0] = x;
+ a[1] = y;
+ for i := 0; i < 2; i++ {
+ go send(c, a[i]);
+ select {
+ case req := <-c:
+ p[i] = &req;
+ }
+ }
+ return p[0], p[1]
+}
+
+func range_escapes(x int) *int {
+ var a [1]int;
+ a[0] = x;
+ for k, v := range a {
+ return &v;
+ }
+ return nil;
+}
+
+// *is* aliased
+func range_escapes2(x, y int) (*int, *int) {
+ var a [2]int;
+ var p [2]*int;
+ a[0] = x;
+ a[1] = y;
+ for k, v := range a {
+ p[k] = &v;
+ }
+ return p[0], p[1]
+}
+
+// *is* aliased
+func for_escapes2(x int, y int) (*int, *int) {
+ var p [2]*int;
+ n := 0;
+ for i := x; n < 2; i = y {
+ p[n] = &i;
+ n++;
+ }
+ return p[0], p[1]
+}
+
+func main() {
+ p, q := i_escapes(1), i_escapes(2);
+ chk(p, q, 1, "i_escapes");
+
+ p, q = j_escapes(3), j_escapes(4);
+ chk(p, q, 3, "j_escapes");
+
+ p, q = k_escapes(5), k_escapes(6);
+ chk(p, q, 5, "k_escapes");
+
+ p, q = in_escapes(7), in_escapes(8);
+ chk(p, q, 7, "in_escapes");
+
+ p, q = select_escapes(9), select_escapes(10);
+ chk(p, q, 9, "select_escapes");
+
+ p, q = select_escapes1(11, 12);
+ chk(p, q, 11, "select_escapes1");
+
+ p, q = range_escapes(13), range_escapes(14);
+ chk(p, q, 13, "range_escapes");
+
+ p, q = range_escapes2(101, 102);
+ chkalias(p, q, 101, "range_escapes2");
+
+ p, q = for_escapes2(103, 104);
+ chkalias(p, q, 103, "for_escapes2");
+
+ if bad {
+ panic("BUG: no escape");
+ }
+}