summaryrefslogtreecommitdiff
path: root/src/cmd/gc/fmt.c
diff options
context:
space:
mode:
authorRuss Cox <rsc@golang.org>2014-02-13 20:59:39 -0500
committerRuss Cox <rsc@golang.org>2014-02-13 20:59:39 -0500
commite0ed119d47728176de20aedeb519e6b470e7e411 (patch)
treeeaaf55c2dd390512ef6c54ada8e4bab5b7c83842 /src/cmd/gc/fmt.c
parent627d914dff9f9b31d835a6aaa57073364c13638a (diff)
downloadgo-e0ed119d47728176de20aedeb519e6b470e7e411.tar.gz
cmd/gc: distinguish unnamed vs blank-named return variables better
Before, an unnamed return value turned into an ONAME node n with n->sym named ~anon%d, and n->orig == n. A blank-named return value turned into an ONAME node n with n->sym named ~anon%d but n->orig == the original blank n. Code generation and printing uses n->orig, so that this node formatted as _. But some code does not use n->orig. In particular the liveness code does not know about the n->orig convention and so mishandles blank identifiers. It is possible to fix but seemed better to avoid the confusion entirely. Now the first kind of node is named ~r%d and the second ~b%d; both have n->orig == n, so that it doesn't matter whether code uses n or n->orig. After this change the ->orig field is only used for other kinds of expressions, not for ONAME nodes. This requires distinguishing ~b from ~r names in a few places that care. It fixes a liveness analysis bug without actually changing the liveness code. TBR=ken2 CC=golang-codereviews https://codereview.appspot.com/63630043
Diffstat (limited to 'src/cmd/gc/fmt.c')
-rw-r--r--src/cmd/gc/fmt.c16
1 files changed, 12 insertions, 4 deletions
diff --git a/src/cmd/gc/fmt.c b/src/cmd/gc/fmt.c
index 6f40c7ff3..bffe8dfc7 100644
--- a/src/cmd/gc/fmt.c
+++ b/src/cmd/gc/fmt.c
@@ -678,12 +678,17 @@ typefmt(Fmt *fp, Type *t)
if(!(fp->flags&FmtShort)) {
s = t->sym;
- // Take the name from the original, lest we substituted it with ~anon%d
+ // Take the name from the original, lest we substituted it with ~r%d or ~b%d.
+ // ~r%d is a (formerly) unnamed result.
if ((fmtmode == FErr || fmtmode == FExp) && t->nname != N) {
if(t->nname->orig != N) {
s = t->nname->orig->sym;
- if(s != S && s->name[0] == '~')
- s = S;
+ if(s != S && s->name[0] == '~') {
+ if(s->name[1] == 'r') // originally an unnamed result
+ s = S;
+ else if(s->name[1] == 'b') // originally the blank identifier _
+ s = lookup("_");
+ }
} else
s = S;
}
@@ -1104,7 +1109,10 @@ exprfmt(Fmt *f, Node *n, int prec)
case PAUTO:
case PPARAM:
case PPARAMOUT:
- if(fmtmode == FExp && n->sym && !isblanksym(n->sym) && n->vargen > 0)
+ // _ becomes ~b%d internally; print as _ for export
+ if(fmtmode == FExp && n->sym && n->sym->name[0] == '~' && n->sym->name[1] == 'b')
+ return fmtprint(f, "_");
+ if(fmtmode == FExp && n->sym && !isblank(n) && n->vargen > 0)
return fmtprint(f, "%S·%d", n->sym, n->vargen);
}