github.com/euank/go@v0.0.0-20160829210321-495514729181/src/cmd/compile/internal/gc/testdata/namedReturn.go (about)

     1  // run
     2  
     3  // Copyright 2016 The Go Authors. All rights reserved.
     4  // Use of this source code is governed by a BSD-style
     5  // license that can be found in the LICENSE file.
     6  
     7  // This test makes sure that naming named
     8  // return variables in a return statement works.
     9  // See issue #14904.
    10  
    11  package main
    12  
    13  import (
    14  	"fmt"
    15  	"runtime"
    16  )
    17  
    18  // Our heap-allocated object that will be GC'd incorrectly.
    19  // Note that we always check the second word because that's
    20  // where 0xdeaddeaddeaddead is written.
    21  type B [4]int
    22  
    23  // small (SSAable) array
    24  type T1 [3]*B
    25  
    26  //go:noinline
    27  func f1() (t T1) {
    28  	t[0] = &B{91, 92, 93, 94}
    29  	runtime.GC()
    30  	return t
    31  }
    32  
    33  // large (non-SSAable) array
    34  type T2 [8]*B
    35  
    36  //go:noinline
    37  func f2() (t T2) {
    38  	t[0] = &B{91, 92, 93, 94}
    39  	runtime.GC()
    40  	return t
    41  }
    42  
    43  // small (SSAable) struct
    44  type T3 struct {
    45  	a, b, c *B
    46  }
    47  
    48  //go:noinline
    49  func f3() (t T3) {
    50  	t.a = &B{91, 92, 93, 94}
    51  	runtime.GC()
    52  	return t
    53  }
    54  
    55  // large (non-SSAable) struct
    56  type T4 struct {
    57  	a, b, c, d, e, f *B
    58  }
    59  
    60  //go:noinline
    61  func f4() (t T4) {
    62  	t.a = &B{91, 92, 93, 94}
    63  	runtime.GC()
    64  	return t
    65  }
    66  
    67  var sink *B
    68  
    69  func f5() int {
    70  	b := &B{91, 92, 93, 94}
    71  	t := T4{b, nil, nil, nil, nil, nil}
    72  	sink = b   // make sure b is heap allocated ...
    73  	sink = nil // ... but not live
    74  	runtime.GC()
    75  	t = t
    76  	return t.a[1]
    77  }
    78  
    79  func main() {
    80  	failed := false
    81  
    82  	if v := f1()[0][1]; v != 92 {
    83  		fmt.Printf("f1()[0][1]=%d, want 92\n", v)
    84  		failed = true
    85  	}
    86  	if v := f2()[0][1]; v != 92 {
    87  		fmt.Printf("f2()[0][1]=%d, want 92\n", v)
    88  		failed = true
    89  	}
    90  	if v := f3().a[1]; v != 92 {
    91  		fmt.Printf("f3().a[1]=%d, want 92\n", v)
    92  		failed = true
    93  	}
    94  	if v := f4().a[1]; v != 92 {
    95  		fmt.Printf("f4().a[1]=%d, want 92\n", v)
    96  		failed = true
    97  	}
    98  	if v := f5(); v != 92 {
    99  		fmt.Printf("f5()=%d, want 92\n", v)
   100  		failed = true
   101  	}
   102  	if failed {
   103  		panic("bad")
   104  	}
   105  }