Commit 38e9b077 authored by Russ Cox's avatar Russ Cox

cmd/gc: fix escape analysis of method values

R=ken2
CC=golang-dev
https://golang.org/cl/7518050
parent 0ad265d4
......@@ -270,8 +270,9 @@ typecheckpartialcall(Node *fn, Node *sym)
// Create top-level function.
fn->nname = makepartialcall(fn, fn->type, sym);
fn->right = sym;
fn->op = OCALLPART;
fn->type = fn->right->type;
fn->type = fn->nname->type;
}
static Node*
......
......@@ -597,6 +597,14 @@ esc(EscState *e, Node *n)
escassign(e, &e->theSink, n->left);
break;
case OCALLPART:
n->esc = EscNone; // until proven otherwise
e->noesc = list(e->noesc, n);
n->escloopdepth = e->loopdepth;
// Contents make it to memory, lose track.
escassign(e, &e->theSink, n->left);
break;
case OMAPLIT:
n->esc = EscNone; // until proven otherwise
e->noesc = list(e->noesc, n);
......@@ -667,6 +675,7 @@ escassign(EscState *e, Node *dst, Node *src)
case OCONVNOP:
case OMAPLIT:
case OSTRUCTLIT:
case OCALLPART:
break;
case ONAME:
......@@ -713,6 +722,7 @@ escassign(EscState *e, Node *dst, Node *src)
case OMAKESLICE:
case ONEW:
case OCLOSURE:
case OCALLPART:
escflows(e, dst, src);
break;
......@@ -1073,6 +1083,7 @@ escwalk(EscState *e, int level, Node *dst, Node *src)
case OMAPLIT:
case ONEW:
case OCLOSURE:
case OCALLPART:
if(leaks) {
src->esc = EscHeap;
if(debug['m'])
......
......@@ -1022,6 +1022,7 @@ static int opprec[] = {
[ODOTTYPE] = 8,
[ODOT] = 8,
[OXDOT] = 8,
[OCALLPART] = 8,
[OPLUS] = 7,
[ONOT] = 7,
......@@ -1269,9 +1270,10 @@ exprfmt(Fmt *f, Node *n, int prec)
case ODOTPTR:
case ODOTINTER:
case ODOTMETH:
case OCALLPART:
exprfmt(f, n->left, nprec);
if(n->right == N || n->right->sym == S)
fmtstrcpy(f, ".<nil>");
return fmtstrcpy(f, ".<nil>");
return fmtprint(f, ".%hhS", n->right->sym);
case ODOTTYPE:
......
......@@ -1303,3 +1303,25 @@ func G() {
var buf4 [10]byte // ERROR "moved to heap: buf4"
F4(buf4[:]) // ERROR "buf4 escapes to heap"
}
type Tm struct {
x int
}
func (t *Tm) M() { // ERROR "t does not escape"
}
func foo141() {
var f func()
t := new(Tm) // ERROR "escapes to heap"
f = t.M // ERROR "t.M does not escape"
_ = f
}
var gf func()
func foo142() {
t := new(Tm) // ERROR "escapes to heap"
gf = t.M // ERROR "t.M escapes to heap"
}
// run
// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Bug in method values: escape analysis was off.
package main
import "sync"
var called = false
type T struct {
once sync.Once
}
func (t *T) M() {
called = true
}
func main() {
var t T
t.once.Do(t.M)
if !called {
panic("not called")
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment