// $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");
	}
}
