diff options
author | Russ Cox <rsc@golang.org> | 2009-01-29 17:38:58 -0800 |
---|---|---|
committer | Russ Cox <rsc@golang.org> | 2009-01-29 17:38:58 -0800 |
commit | 82411b9886df9e9b8f2c05b0804432c3141419b3 (patch) | |
tree | 346d845fb120717e657f7a2919d374290fe02f81 /test/escape.go | |
parent | 4a2c6c1eafc88455ffc4b1867e922e76f3a7782b (diff) | |
download | go-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.go | 175 |
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"); + } +} |