1// errorcheck -0 -m -l 2 3// Copyright 2015 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// Test escape analysis for arrays and some large things 8 9package foo 10 11var Ssink *string 12 13type U [2]*string 14 15func bar(a, b *string) U { // ERROR "leaking param: a to result ~r0 level=0$" "leaking param: b to result ~r0 level=0$" 16 return U{a, b} 17} 18 19func foo(x U) U { // ERROR "leaking param: x to result ~r0 level=0$" 20 return U{x[1], x[0]} 21} 22 23func bff(a, b *string) U { // ERROR "leaking param: a to result ~r0 level=0$" "leaking param: b to result ~r0 level=0$" 24 return foo(foo(bar(a, b))) 25} 26 27func tbff1() *string { 28 a := "cat" 29 b := "dog" // ERROR "moved to heap: b$" 30 u := bff(&a, &b) 31 _ = u[0] 32 return &b 33} 34 35// BAD: need fine-grained analysis to track u[0] and u[1] differently. 36func tbff2() *string { 37 a := "cat" // ERROR "moved to heap: a$" 38 b := "dog" // ERROR "moved to heap: b$" 39 u := bff(&a, &b) 40 _ = u[0] 41 return u[1] 42} 43 44func car(x U) *string { // ERROR "leaking param: x to result ~r0 level=0$" 45 return x[0] 46} 47 48// BAD: need fine-grained analysis to track x[0] and x[1] differently. 49func fun(x U, y *string) *string { // ERROR "leaking param: x to result ~r0 level=0$" "leaking param: y to result ~r0 level=0$" 50 x[0] = y 51 return x[1] 52} 53 54func fup(x *U, y *string) *string { // ERROR "leaking param: x to result ~r0 level=1$" "leaking param: y$" 55 x[0] = y // leaking y to heap is intended 56 return x[1] 57} 58 59func fum(x *U, y **string) *string { // ERROR "leaking param: x to result ~r0 level=1$" "leaking param content: y$" 60 x[0] = *y 61 return x[1] 62} 63 64func fuo(x *U, y *U) *string { // ERROR "leaking param: x to result ~r0 level=1$" "leaking param content: y$" 65 x[0] = y[0] 66 return x[1] 67} 68 69// These two tests verify that: 70// small array literals are stack allocated; 71// pointers stored in small array literals do not escape; 72// large array literals are heap allocated; 73// pointers stored in large array literals escape. 74func hugeLeaks1(x **string, y **string) { // ERROR "leaking param content: x" "y does not escape" 75 a := [10]*string{*y} 76 _ = a 77 // 4 x 4,000,000 exceeds MaxStackVarSize, therefore it must be heap allocated if pointers are 4 bytes or larger. 78 b := [4000000]*string{*x} // ERROR "moved to heap: b" 79 _ = b 80} 81 82func hugeLeaks2(x *string, y *string) { // ERROR "leaking param: x" "y does not escape" 83 a := [10]*string{y} 84 _ = a 85 // 4 x 4,000,000 exceeds MaxStackVarSize, therefore it must be heap allocated if pointers are 4 bytes or larger. 86 b := [4000000]*string{x} // ERROR "moved to heap: b" 87 _ = b 88} 89 90// BAD: x need not leak. 91func doesNew1(x *string, y *string) { // ERROR "leaking param: x" "leaking param: y" 92 a := new([10]*string) // ERROR "new\(\[10\]\*string\) does not escape" 93 a[0] = x 94 b := new([65537]*string) // ERROR "new\(\[65537\]\*string\) escapes to heap" 95 b[0] = y 96} 97 98type a10 struct { 99 s *string 100 i [10]int32 101} 102 103type a65537 struct { 104 s *string 105 i [65537]int32 106} 107 108// BAD: x need not leak. 109func doesNew2(x *string, y *string) { // ERROR "leaking param: x" "leaking param: y" 110 a := new(a10) // ERROR "new\(a10\) does not escape" 111 a.s = x 112 b := new(a65537) // ERROR "new\(a65537\) escapes to heap" 113 b.s = y 114} 115 116// BAD: x need not leak. 117func doesMakeSlice(x *string, y *string) { // ERROR "leaking param: x" "leaking param: y" 118 a := make([]*string, 10) // ERROR "make\(\[\]\*string, 10\) does not escape" 119 a[0] = x 120 b := make([]*string, 65537) // ERROR "make\(\[\]\*string, 65537\) escapes to heap" 121 b[0] = y 122} 123 124func nonconstArray() { 125 n := 32 126 s1 := make([]int, n) // ERROR "make\(\[\]int, n\) escapes to heap" 127 s2 := make([]int, 0, n) // ERROR "make\(\[\]int, 0, n\) escapes to heap" 128 _, _ = s1, s2 129} 130