blob: ac51fe7ca66af10a09db1d81328002984a1bae99 [file] [log] [blame]
David Chase7fbb1b32015-03-26 16:36:15 -04001// 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 function parameters.
8
9// In this test almost everything is BAD except the simplest cases
10// where input directly flows to output.
11
12package foo
13
14var Ssink *string
15
16type U [2]*string
17
18func bar(a, b *string) U { // ERROR "leaking param: a to result ~r2 level=0$" "leaking param: b to result ~r2 level=0$"
19 return U{a, b}
20}
21
22func foo(x U) U { // ERROR "leaking param: x to result ~r1 level=0$"
23 return U{x[1], x[0]}
24}
25
26func bff(a, b *string) U { // ERROR "leaking param: a to result ~r2 level=0$" "leaking param: b to result ~r2 level=0$"
27 return foo(foo(bar(a, b)))
28}
29
30func tbff1() *string {
31 a := "cat"
32 b := "dog" // ERROR "moved to heap: b$"
33 u := bff(&a, &b) // ERROR "tbff1 &a does not escape$" "tbff1 &b does not escape$"
34 _ = u[0]
35 return &b // ERROR "&b escapes to heap$"
36}
37
38// BAD: need fine-grained analysis to track u[0] and u[1] differently.
39func tbff2() *string {
40 a := "cat" // ERROR "moved to heap: a$"
41 b := "dog" // ERROR "moved to heap: b$"
42 u := bff(&a, &b) // ERROR "&a escapes to heap$" "&b escapes to heap$"
43 _ = u[0]
44 return u[1]
45}
46
47func car(x U) *string { // ERROR "leaking param: x to result ~r1 level=0$"
48 return x[0]
49}
50
51// BAD: need fine-grained analysis to track x[0] and x[1] differently.
52func fun(x U, y *string) *string { // ERROR "leaking param: x to result ~r2 level=0$" "leaking param: y to result ~r2 level=0$"
53 x[0] = y
54 return x[1]
55}
56
57func fup(x *U, y *string) *string { // ERROR "leaking param: x to result ~r2 level=1$" "leaking param: y$"
58 x[0] = y // leaking y to heap is intended
59 return x[1]
60}
61
62// BAD: would be nice to record that *y (content) is what leaks, not y itself
63func fum(x *U, y **string) *string { // ERROR "leaking param: x to result ~r2 level=1$" "leaking param content: y$"
64 x[0] = *y
65 return x[1]
66}
67
68// BAD: would be nice to record that y[0] (content) is what leaks, not y itself
69func fuo(x *U, y *U) *string { // ERROR "leaking param: x to result ~r2 level=1$" "leaking param content: y$"
70 x[0] = y[0]
71 return x[1]
72}