From: Russ Cox Date: Sun, 3 Feb 2013 06:18:28 +0000 (-0500) Subject: cmd/gc: elide self-assignment during return X-Git-Tag: go1.1rc2~1173 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=2eafbb8878ffc5a032fdc9361ed75731da5bb698;p=gostls13.git 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 --- diff --git a/src/cmd/gc/walk.c b/src/cmd/gc/walk.c index 0185a0f9f4..911e0a4dd5 100644 --- a/src/cmd/gc/walk.c +++ b/src/cmd/gc/walk.c @@ -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) diff --git a/src/pkg/runtime/race/testdata/regression_test.go b/src/pkg/runtime/race/testdata/regression_test.go index c48f7b8600..066ccbb38e 100644 --- a/src/pkg/runtime/race/testdata/regression_test.go +++ b/src/pkg/runtime/race/testdata/regression_test.go @@ -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 +}