github.com/go-asm/go@v1.21.1-0.20240213172139-40c5ead50c48/cmd/compile/test/testdata/namedReturn_test.go (about)

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