mirror of https://github.com/golang/go.git
cmd/gc: fix escape analysis for &x inside switch x := v.(type)
The analysis for &x was using the loop depth on x set during x's declaration. A type switch creates a list of implicit declarations that were not getting initialized with loop depths. Fixes #8176. LGTM=iant R=iant CC=golang-codereviews https://golang.org/cl/108860043
This commit is contained in:
parent
3ad9df0422
commit
775ab8eeaa
|
|
@ -442,6 +442,18 @@ esc(EscState *e, Node *n, Node *up)
|
||||||
if(n->op == OFOR || n->op == ORANGE)
|
if(n->op == OFOR || n->op == ORANGE)
|
||||||
e->loopdepth++;
|
e->loopdepth++;
|
||||||
|
|
||||||
|
// type switch variables have no ODCL.
|
||||||
|
// process type switch as declaration.
|
||||||
|
// must happen before processing of switch body,
|
||||||
|
// so before recursion.
|
||||||
|
if(n->op == OSWITCH && n->ntest && n->ntest->op == OTYPESW) {
|
||||||
|
for(ll=n->list; ll; ll=ll->next) { // cases
|
||||||
|
// ll->n->nname is the variable per case
|
||||||
|
if(ll->n->nname)
|
||||||
|
ll->n->nname->escloopdepth = e->loopdepth;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
esc(e, n->left, n);
|
esc(e, n->left, n);
|
||||||
esc(e, n->right, n);
|
esc(e, n->right, n);
|
||||||
esc(e, n->ntest, n);
|
esc(e, n->ntest, n);
|
||||||
|
|
@ -658,8 +670,10 @@ esc(EscState *e, Node *n, Node *up)
|
||||||
// current loop depth is an upper bound on actual loop depth
|
// current loop depth is an upper bound on actual loop depth
|
||||||
// of addressed value.
|
// of addressed value.
|
||||||
n->escloopdepth = e->loopdepth;
|
n->escloopdepth = e->loopdepth;
|
||||||
// for &x, use loop depth of x.
|
// for &x, use loop depth of x if known.
|
||||||
if(n->left->op == ONAME) {
|
// it should always be known, but if not, be conservative
|
||||||
|
// and keep the current loop depth.
|
||||||
|
if(n->left->op == ONAME && (n->left->escloopdepth != 0 || n->left->class == PPARAMOUT)) {
|
||||||
switch(n->left->class) {
|
switch(n->left->class) {
|
||||||
case PAUTO:
|
case PAUTO:
|
||||||
case PPARAM:
|
case PPARAM:
|
||||||
|
|
|
||||||
|
|
@ -1468,3 +1468,13 @@ func foo152() {
|
||||||
v := NewV(u)
|
v := NewV(u)
|
||||||
println(v)
|
println(v)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// issue 8176 - &x in type switch body not marked as escaping
|
||||||
|
|
||||||
|
func foo153(v interface{}) *int { // ERROR "leaking param: v"
|
||||||
|
switch x := v.(type) {
|
||||||
|
case int: // ERROR "moved to heap: x"
|
||||||
|
return &x // ERROR "&x escapes to heap"
|
||||||
|
}
|
||||||
|
panic(0)
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue