aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/gc
diff options
context:
space:
mode:
authorRuss Cox <rsc@golang.org>2014-06-11 11:48:47 -0400
committerRuss Cox <rsc@golang.org>2014-06-11 11:48:47 -0400
commit775ab8eeaaea970ddfcb339c275f79cd98e6bca5 (patch)
tree8a3f4ac7c18a9218304671d821472710f888815f /src/cmd/gc
parent3ad9df0422213468e22078bf5957fcc2fcafc391 (diff)
downloadgo-775ab8eeaaea970ddfcb339c275f79cd98e6bca5.tar.xz
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
Diffstat (limited to 'src/cmd/gc')
-rw-r--r--src/cmd/gc/esc.c18
1 files changed, 16 insertions, 2 deletions
diff --git a/src/cmd/gc/esc.c b/src/cmd/gc/esc.c
index a75517813d..9d7dc1149c 100644
--- a/src/cmd/gc/esc.c
+++ b/src/cmd/gc/esc.c
@@ -442,6 +442,18 @@ esc(EscState *e, Node *n, Node *up)
if(n->op == OFOR || n->op == ORANGE)
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->right, 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
// of addressed value.
n->escloopdepth = e->loopdepth;
- // for &x, use loop depth of x.
- if(n->left->op == ONAME) {
+ // for &x, use loop depth of x if known.
+ // 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) {
case PAUTO:
case PPARAM: