Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
go
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
go
Commits
b4df33a6
Commit
b4df33a6
authored
Nov 01, 2011
by
Russ Cox
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
gc: test + fix escape analysis bug
R=lvd CC=golang-dev
https://golang.org/cl/5333049
parent
1fe22d2d
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
89 additions
and
70 deletions
+89
-70
src/cmd/gc/esc.c
src/cmd/gc/esc.c
+1
-0
test/escape2.go
test/escape2.go
+88
-70
No files found.
src/cmd/gc/esc.c
View file @
b4df33a6
...
...
@@ -239,6 +239,7 @@ esc(Node *n)
case
OPROC
:
// go f(x) - f and x escape
escassign
(
&
theSink
,
n
->
left
->
left
);
escassign
(
&
theSink
,
n
->
left
->
right
);
// ODDDARG for call
for
(
ll
=
n
->
left
->
list
;
ll
;
ll
=
ll
->
next
)
escassign
(
&
theSink
,
ll
->
n
);
break
;
...
...
test/escape2.go
View file @
b4df33a6
...
...
@@ -6,12 +6,15 @@
package
foo
import
"unsafe"
import
(
"fmt"
"unsafe"
)
var
gxx
*
int
func
foo1
(
x
int
)
{
// ERROR "moved to heap: x"
gxx
=
&
x
// ERROR "&x escapes to heap"
gxx
=
&
x
// ERROR "&x escapes to heap"
}
func
foo2
(
yy
*
int
)
{
// ERROR "leaking param: yy"
...
...
@@ -19,7 +22,7 @@ func foo2(yy *int) { // ERROR "leaking param: yy"
}
func
foo3
(
x
int
)
*
int
{
// ERROR "moved to heap: x"
return
&
x
// ERROR "&x escapes to heap"
return
&
x
// ERROR "&x escapes to heap"
}
type
T
*
T
...
...
@@ -35,7 +38,7 @@ func foo4(xx, yy *int) { // ERROR "xx does not escape" "yy does not escape"
// xx isn't going anywhere, so taking address of yy is ok
func
foo5
(
xx
**
int
,
yy
*
int
)
{
// ERROR "xx does not escape" "yy does not escape"
xx
=
&
yy
// ERROR "&yy does not escape"
xx
=
&
yy
// ERROR "&yy does not escape"
}
func
foo6
(
xx
**
int
,
yy
*
int
)
{
// ERROR "xx does not escape" "leaking param: yy"
...
...
@@ -62,8 +65,8 @@ func foo10(xx, yy *int) { // ERROR "xx does not escape" "yy does not escape"
func
foo11
()
int
{
x
,
y
:=
0
,
42
xx
:=
&
x
// ERROR "&x does not escape"
yy
:=
&
y
// ERROR "&y does not escape"
xx
:=
&
x
// ERROR "&x does not escape"
yy
:=
&
y
// ERROR "&y does not escape"
*
xx
=
*
yy
return
x
}
...
...
@@ -83,7 +86,7 @@ func foo14(yyy **int) { // ERROR "yyy does not escape"
}
func
foo15
(
yy
*
int
)
{
// ERROR "moved to heap: yy"
xxx
=
&
yy
// ERROR "&yy escapes to heap"
xxx
=
&
yy
// ERROR "&yy escapes to heap"
}
func
foo16
(
yy
*
int
)
{
// ERROR "leaking param: yy"
...
...
@@ -95,7 +98,7 @@ func foo17(yy *int) { // ERROR "yy does not escape"
}
func
foo18
(
y
int
)
{
// ERROR "moved to heap: "y"
*
xxx
=
&
y
// ERROR "&y escapes to heap"
*
xxx
=
&
y
// ERROR "&y escapes to heap"
}
func
foo19
(
y
int
)
{
...
...
@@ -127,7 +130,7 @@ func (b *Bar) AlsoNoLeak() *int { // ERROR "b does not escape"
return
b
.
ii
}
func
goLeak
(
b
*
Bar
)
{
// ERROR "leaking param: b"
func
goLeak
(
b
*
Bar
)
{
// ERROR "leaking param: b"
go
b
.
NoLeak
()
}
...
...
@@ -145,7 +148,7 @@ func (b *Bar2) NoLeak() int { // ERROR "b does not escape"
}
func
(
b
*
Bar2
)
Leak
()
[]
int
{
// ERROR "leaking param: b"
return
b
.
i
[
:
]
// ERROR "&b.i escapes to heap"
return
b
.
i
[
:
]
// ERROR "&b.i escapes to heap"
}
func
(
b
*
Bar2
)
AlsoNoLeak
()
[]
int
{
// ERROR "b does not escape"
...
...
@@ -153,49 +156,49 @@ func (b *Bar2) AlsoNoLeak() []int { // ERROR "b does not escape"
}
func
(
b
*
Bar2
)
LeakSelf
()
{
// ERROR "leaking param: b"
b
.
ii
=
b
.
i
[
0
:
4
]
// ERROR "&b.i escapes to heap"
b
.
ii
=
b
.
i
[
0
:
4
]
// ERROR "&b.i escapes to heap"
}
func
(
b
*
Bar2
)
LeakSelf2
()
{
// ERROR "leaking param: b"
var
buf
[]
int
buf
=
b
.
i
[
0
:
]
// ERROR "&b.i escapes to heap"
buf
=
b
.
i
[
0
:
]
// ERROR "&b.i escapes to heap"
b
.
ii
=
buf
}
func
foo21
()
func
()
int
{
x
:=
42
// ERROR "moved to heap: x"
return
func
()
int
{
// ERROR "func literal escapes to heap"
return
x
// ERROR "&x escapes to heap"
x
:=
42
// ERROR "moved to heap: x"
return
func
()
int
{
// ERROR "func literal escapes to heap"
return
x
// ERROR "&x escapes to heap"
}
}
func
foo22
()
int
{
x
:=
42
return
func
()
int
{
// ERROR "func literal does not escape"
return
func
()
int
{
// ERROR "func literal does not escape"
return
x
}()
}
func
foo23
(
x
int
)
func
()
int
{
// ERROR "moved to heap: x"
return
func
()
int
{
// ERROR "func literal escapes to heap"
return
x
// ERROR "&x escapes to heap"
return
func
()
int
{
// ERROR "func literal escapes to heap"
return
x
// ERROR "&x escapes to heap"
}
}
func
foo23a
(
x
int
)
func
()
int
{
// ERROR "moved to heap: x"
f
:=
func
()
int
{
// ERROR "func literal escapes to heap"
return
x
// ERROR "&x escapes to heap"
f
:=
func
()
int
{
// ERROR "func literal escapes to heap"
return
x
// ERROR "&x escapes to heap"
}
return
f
}
func
foo23b
(
x
int
)
*
(
func
()
int
)
{
// ERROR "moved to heap: x"
f
:=
func
()
int
{
return
x
}
// ERROR "moved to heap: f" "func literal escapes to heap" "&x escapes to heap"
return
&
f
// ERROR "&f escapes to heap"
return
&
f
// ERROR "&f escapes to heap"
}
func
foo24
(
x
int
)
int
{
return
func
()
int
{
// ERROR "func literal does not escape"
return
func
()
int
{
// ERROR "func literal does not escape"
return
x
}()
}
...
...
@@ -212,11 +215,11 @@ func foonoleak(xx *int) int { // ERROR "xx does not escape"
}
func
foo31
(
x
int
)
int
{
// ERROR "moved to heap: x"
return
fooleak
(
&
x
)
// ERROR "&x escapes to heap"
return
fooleak
(
&
x
)
// ERROR "&x escapes to heap"
}
func
foo32
(
x
int
)
int
{
return
foonoleak
(
&
x
)
// ERROR "&x does not escape"
return
foonoleak
(
&
x
)
// ERROR "&x does not escape"
}
type
Foo
struct
{
...
...
@@ -244,15 +247,15 @@ func (f *Foo) NoLeak() { // ERROR "f does not escape"
}
func
foo41
(
x
int
)
{
// ERROR "moved to heap: x"
F
.
xx
=
&
x
// ERROR "&x escapes to heap"
F
.
xx
=
&
x
// ERROR "&x escapes to heap"
}
func
(
f
*
Foo
)
foo42
(
x
int
)
{
// ERROR "f does not escape" "moved to heap: x"
f
.
xx
=
&
x
// ERROR "&x escapes to heap"
f
.
xx
=
&
x
// ERROR "&x escapes to heap"
}
func
foo43
(
f
*
Foo
,
x
int
)
{
// ERROR "f does not escape" "moved to heap: x"
f
.
xx
=
&
x
// ERROR "&x escapes to heap"
f
.
xx
=
&
x
// ERROR "&x escapes to heap"
}
func
foo44
(
yy
*
int
)
{
// ERROR "leaking param: yy"
...
...
@@ -268,7 +271,7 @@ func (f *Foo) foo46() { // ERROR "f does not escape"
}
func
(
f
*
Foo
)
foo47
()
{
// ERROR "leaking param: f"
f
.
xx
=
&
f
.
x
// ERROR "&f.x escapes to heap"
f
.
xx
=
&
f
.
x
// ERROR "&f.x escapes to heap"
}
var
ptrSlice
[]
*
int
...
...
@@ -284,38 +287,38 @@ func foo51(i *int) { // ERROR "leaking param: i"
}
func
indaddr1
(
x
int
)
*
int
{
// ERROR "moved to heap: x"
return
&
x
// ERROR "&x escapes to heap"
return
&
x
// ERROR "&x escapes to heap"
}
func
indaddr2
(
x
*
int
)
*
int
{
// ERROR "leaking param: x"
return
*&
x
// ERROR "&x does not escape"
return
*&
x
// ERROR "&x does not escape"
}
func
indaddr3
(
x
*
int32
)
*
int
{
// ERROR "leaking param: x"
return
*
(
**
int
)(
unsafe
.
Pointer
(
&
x
))
// ERROR "&x does not escape"
return
*
(
**
int
)(
unsafe
.
Pointer
(
&
x
))
// ERROR "&x does not escape"
}
// From package math:
func
Float32bits
(
f
float32
)
uint32
{
return
*
(
*
uint32
)(
unsafe
.
Pointer
(
&
f
))
// ERROR "&f does not escape"
return
*
(
*
uint32
)(
unsafe
.
Pointer
(
&
f
))
// ERROR "&f does not escape"
}
func
Float32frombits
(
b
uint32
)
float32
{
return
*
(
*
float32
)(
unsafe
.
Pointer
(
&
b
))
// ERROR "&b does not escape"
return
*
(
*
float32
)(
unsafe
.
Pointer
(
&
b
))
// ERROR "&b does not escape"
}
func
Float64bits
(
f
float64
)
uint64
{
return
*
(
*
uint64
)(
unsafe
.
Pointer
(
&
f
))
// ERROR "&f does not escape"
return
*
(
*
uint64
)(
unsafe
.
Pointer
(
&
f
))
// ERROR "&f does not escape"
}
func
Float64frombits
(
b
uint64
)
float64
{
return
*
(
*
float64
)(
unsafe
.
Pointer
(
&
b
))
// ERROR "&b does not escape"
return
*
(
*
float64
)(
unsafe
.
Pointer
(
&
b
))
// ERROR "&b does not escape"
}
// contrast with
func
float64bitsptr
(
f
float64
)
*
uint64
{
// ERROR "moved to heap: f"
return
(
*
uint64
)(
unsafe
.
Pointer
(
&
f
))
// ERROR "&f escapes to heap"
return
(
*
uint64
)(
unsafe
.
Pointer
(
&
f
))
// ERROR "&f escapes to heap"
}
func
float64ptrbitsptr
(
f
*
float64
)
*
uint64
{
// ERROR "leaking param: f"
...
...
@@ -328,7 +331,7 @@ func typesw(i interface{}) *int { // ERROR "leaking param: i"
return
val
case
*
int8
:
v
:=
int
(
*
val
)
// ERROR "moved to heap: v"
return
&
v
// ERROR "&v escapes to heap"
return
&
v
// ERROR "&v escapes to heap"
}
return
nil
}
...
...
@@ -409,12 +412,12 @@ func (MV) M() {}
func
foo65
()
{
var
mv
MV
foo63
(
&
mv
)
// ERROR "&mv does not escape"
foo63
(
&
mv
)
// ERROR "&mv does not escape"
}
func
foo66
()
{
var
mv
MV
// ERROR "moved to heap: mv"
foo64
(
&
mv
)
// ERROR "&mv escapes to heap"
var
mv
MV
// ERROR "moved to heap: mv"
foo64
(
&
mv
)
// ERROR "&mv escapes to heap"
}
func
foo67
()
{
...
...
@@ -444,20 +447,20 @@ func foo71(x *int) []*int { // ERROR "leaking param: x"
func
foo71a
(
x
int
)
[]
*
int
{
// ERROR "moved to heap: x"
var
y
[]
*
int
y
=
append
(
y
,
&
x
)
// ERROR "&x escapes to heap"
y
=
append
(
y
,
&
x
)
// ERROR "&x escapes to heap"
return
y
}
func
foo72
()
{
var
x
int
var
y
[
1
]
*
int
y
[
0
]
=
&
x
// ERROR "&x does not escape"
y
[
0
]
=
&
x
// ERROR "&x does not escape"
}
func
foo72aa
()
[
10
]
*
int
{
var
x
int
// ERROR "moved to heap: x"
var
y
[
10
]
*
int
y
[
0
]
=
&
x
// ERROR "&x escapes to heap"
y
[
0
]
=
&
x
// ERROR "&x escapes to heap"
return
y
}
...
...
@@ -465,7 +468,7 @@ func foo72a() {
var
y
[
10
]
*
int
for
i
:=
0
;
i
<
10
;
i
++
{
// escapes its scope
x
:=
i
// ERROR "moved to heap: x"
x
:=
i
// ERROR "moved to heap: x"
y
[
i
]
=
&
x
// ERROR "&x escapes to heap"
}
return
...
...
@@ -474,8 +477,8 @@ func foo72a() {
func
foo72b
()
[
10
]
*
int
{
var
y
[
10
]
*
int
for
i
:=
0
;
i
<
10
;
i
++
{
x
:=
i
// ERROR "moved to heap: x"
y
[
i
]
=
&
x
// ERROR "&x escapes to heap"
x
:=
i
// ERROR "moved to heap: x"
y
[
i
]
=
&
x
// ERROR "&x escapes to heap"
}
return
y
}
...
...
@@ -484,10 +487,10 @@ func foo72b() [10]*int {
func
foo73
()
{
s
:=
[]
int
{
3
,
2
,
1
}
// ERROR "\[\]int literal does not escape"
for
_
,
v
:=
range
s
{
vv
:=
v
// ERROR "moved to heap: vv"
vv
:=
v
// ERROR "moved to heap: vv"
// actually just escapes its scope
defer
func
()
{
// ERROR "func literal escapes to heap"
println
(
vv
)
// ERROR "&vv escapes to heap"
println
(
vv
)
// ERROR "&vv escapes to heap"
}()
}
}
...
...
@@ -495,10 +498,10 @@ func foo73() {
func
foo74
()
{
s
:=
[]
int
{
3
,
2
,
1
}
// ERROR "\[\]int literal does not escape"
for
_
,
v
:=
range
s
{
vv
:=
v
// ERROR "moved to heap: vv"
vv
:=
v
// ERROR "moved to heap: vv"
// actually just escapes its scope
fn
:=
func
()
{
// ERROR "func literal escapes to heap"
println
(
vv
)
// ERROR "&vv escapes to heap"
println
(
vv
)
// ERROR "&vv escapes to heap"
}
defer
fn
()
}
...
...
@@ -509,7 +512,7 @@ func myprint(y *int, x ...interface{}) *int { // ERROR "x does not escape" "leak
}
func
myprint1
(
y
*
int
,
x
...
interface
{})
*
interface
{}
{
// ERROR "y does not escape" "leaking param: x"
return
&
x
[
0
]
// ERROR "&x.0. escapes to heap"
return
&
x
[
0
]
// ERROR "&x.0. escapes to heap"
}
func
foo75
(
z
*
int
)
{
// ERROR "leaking param: z"
...
...
@@ -566,12 +569,12 @@ func foo77a(z []interface{}) { // ERROR "leaking param: z"
}
func
foo78
(
z
int
)
*
int
{
// ERROR "moved to heap: z"
return
&
z
// ERROR "&z escapes to heap"
return
&
z
// ERROR "&z escapes to heap"
}
func
foo78a
(
z
int
)
*
int
{
// ERROR "moved to heap: z"
y
:=
&
z
// ERROR "&z escapes to heap"
x
:=
&
y
// ERROR "&y does not escape"
y
:=
&
z
// ERROR "&z escapes to heap"
x
:=
&
y
// ERROR "&y does not escape"
return
*
x
// really return y
}
...
...
@@ -685,7 +688,7 @@ func foo101(m [1]*int) *int { // ERROR "leaking param: m"
// does not leak m
func
foo101a
(
m
[
1
]
*
int
)
*
int
{
// ERROR "m does not escape"
for
i
:=
range
m
{
// ERROR "moved to heap: i"
return
&
i
// ERROR "&i escapes to heap"
return
&
i
// ERROR "&i escapes to heap"
}
return
nil
}
...
...
@@ -703,12 +706,12 @@ func foo103(m [1]*int, x *int) { // ERROR "m does not escape" "x does not escape
var
y
[]
*
int
// does not leak x
func
foo104
(
x
[]
*
int
)
{
// ERROR "x does not escape"
func
foo104
(
x
[]
*
int
)
{
// ERROR "x does not escape"
copy
(
y
,
x
)
}
// does not leak x
func
foo105
(
x
[]
*
int
)
{
// ERROR "x does not escape"
func
foo105
(
x
[]
*
int
)
{
// ERROR "x does not escape"
_
=
append
(
y
,
x
...
)
}
...
...
@@ -726,7 +729,7 @@ func foo108(x *int) map[*int]*int { // ERROR "leaking param: x"
}
func
foo109
(
x
*
int
)
*
int
{
// ERROR "leaking param: x"
m
:=
map
[
*
int
]
*
int
{
x
:
nil
}
// ERROR "map.* literal does not escape"
m
:=
map
[
*
int
]
*
int
{
x
:
nil
}
// ERROR "map.* literal does not escape"
for
k
,
_
:=
range
m
{
return
k
}
...
...
@@ -734,12 +737,12 @@ func foo109(x *int) *int { // ERROR "leaking param: x"
}
func
foo110
(
x
*
int
)
*
int
{
// ERROR "leaking param: x"
m
:=
map
[
*
int
]
*
int
{
nil
:
x
}
// ERROR "map.* literal does not escape"
m
:=
map
[
*
int
]
*
int
{
nil
:
x
}
// ERROR "map.* literal does not escape"
return
m
[
nil
]
}
func
foo111
(
x
*
int
)
*
int
{
// ERROR "leaking param: x"
m
:=
[]
*
int
{
x
}
// ERROR "\[\]\*int literal does not escape"
m
:=
[]
*
int
{
x
}
// ERROR "\[\]\*int literal does not escape"
return
m
[
0
]
}
...
...
@@ -754,7 +757,7 @@ func foo113(x *int) *int { // ERROR "leaking param: x"
}
func
foo114
(
x
*
int
)
*
int
{
// ERROR "leaking param: x"
m
:=
&
Bar
{
ii
:
x
}
// ERROR "&Bar literal does not escape"
m
:=
&
Bar
{
ii
:
x
}
// ERROR "&Bar literal does not escape"
return
m
.
ii
}
...
...
@@ -764,28 +767,28 @@ func foo115(x *int) *int { // ERROR "leaking param: x"
func
foo116
(
b
bool
)
*
int
{
if
b
{
x
:=
1
// ERROR "moved to heap: x"
return
&
x
// ERROR "&x escapes to heap"
x
:=
1
// ERROR "moved to heap: x"
return
&
x
// ERROR "&x escapes to heap"
}
else
{
y
:=
1
// ERROR "moved to heap: y"
return
&
y
// ERROR "&y escapes to heap"
y
:=
1
// ERROR "moved to heap: y"
return
&
y
// ERROR "&y escapes to heap"
}
return
nil
}
func
foo117
(
unknown
func
(
interface
{}))
{
// ERROR "unknown does not escape"
x
:=
1
// ERROR "moved to heap: x"
func
foo117
(
unknown
func
(
interface
{}))
{
// ERROR "unknown does not escape"
x
:=
1
// ERROR "moved to heap: x"
unknown
(
&
x
)
// ERROR "&x escapes to heap"
}
func
foo118
(
unknown
func
(
*
int
))
{
// ERROR "unknown does not escape"
x
:=
1
// ERROR "moved to heap: x"
func
foo118
(
unknown
func
(
*
int
))
{
// ERROR "unknown does not escape"
x
:=
1
// ERROR "moved to heap: x"
unknown
(
&
x
)
// ERROR "&x escapes to heap"
}
func
external
(
*
int
)
func
foo119
(
x
*
int
)
{
// ERROR "leaking param: x"
func
foo119
(
x
*
int
)
{
// ERROR "leaking param: x"
external
(
x
)
}
...
...
@@ -993,3 +996,18 @@ L100:
goto
L99
goto
L100
}
func
foo121
()
{
for
i
:=
0
;
i
<
10
;
i
++
{
defer
myprint
(
nil
,
i
)
// ERROR "[.][.][.] argument escapes to heap"
go
myprint
(
nil
,
i
)
// ERROR "[.][.][.] argument escapes to heap"
}
}
// same as foo121 but check across import
func
foo121b
()
{
for
i
:=
0
;
i
<
10
;
i
++
{
defer
fmt
.
Printf
(
"%d"
,
i
)
// ERROR "[.][.][.] argument escapes to heap"
go
fmt
.
Printf
(
"%d"
,
i
)
// ERROR "[.][.][.] argument escapes to heap"
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment