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 9package main 10 11import ( 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. 19type B [4]int 20 21// small (SSAable) array 22type A1 [3]*B 23 24//go:noinline 25func f1() (t A1) { 26 t[0] = &B{91, 92, 93, 94} 27 runtime.GC() 28 return t 29} 30 31// large (non-SSAable) array 32type A2 [8]*B 33 34//go:noinline 35func f2() (t A2) { 36 t[0] = &B{91, 92, 93, 94} 37 runtime.GC() 38 return t 39} 40 41// small (SSAable) struct 42type A3 struct { 43 a, b, c *B 44} 45 46//go:noinline 47func f3() (t A3) { 48 t.a = &B{91, 92, 93, 94} 49 runtime.GC() 50 return t 51} 52 53// large (non-SSAable) struct 54type A4 struct { 55 a, b, c, d, e, f *B 56} 57 58//go:noinline 59func f4() (t A4) { 60 t.a = &B{91, 92, 93, 94} 61 runtime.GC() 62 return t 63} 64 65var sink *B 66 67func 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 77func 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} 94