cmd/gc: elide self-assignment during return

More efficient, less racy code.

Fixes #4014.

R=ken2, ken
CC=golang-dev
https://golang.org/cl/7275047
This commit is contained in:
Russ Cox 2013-02-03 01:18:28 -05:00
parent ffc742b658
commit 2eafbb8878
2 changed files with 23 additions and 1 deletions

View file

@ -1326,8 +1326,12 @@ ascompatee(int op, NodeList *nl, NodeList *nr, NodeList **init)
lr->n = safeexpr(lr->n, init);
nn = nil;
for(ll=nl, lr=nr; ll && lr; ll=ll->next, lr=lr->next)
for(ll=nl, lr=nr; ll && lr; ll=ll->next, lr=lr->next) {
// Do not generate 'x = x' during return. See issue 4014.
if(op == ORETURN && ll->n == lr->n)
continue;
nn = list(nn, ascompatee1(op, ll->n, lr->n, init));
}
// cannot happen: caller checked that lists had same length
if(ll || lr)

View file

@ -127,3 +127,21 @@ func divInSlice() {
i := 1
_ = v[(i*4)/3]
}
func TestNoRaceReturn(t *testing.T) {
c := make(chan int)
noRaceReturn(c)
<-c
}
// Return used to do an implicit a = a, causing a read/write race
// with the goroutine. Compiler has an optimization to avoid that now.
// See issue 4014.
func noRaceReturn(c chan int) (a, b int) {
a = 42
go func() {
_ = a
c <- 1
}()
return a, 10
}