]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/gc: elide self-assignment during return
authorRuss Cox <rsc@golang.org>
Sun, 3 Feb 2013 06:18:28 +0000 (01:18 -0500)
committerRuss Cox <rsc@golang.org>
Sun, 3 Feb 2013 06:18:28 +0000 (01:18 -0500)
More efficient, less racy code.

Fixes #4014.

R=ken2, ken
CC=golang-dev
https://golang.org/cl/7275047

src/cmd/gc/walk.c
src/pkg/runtime/race/testdata/regression_test.go

index 0185a0f9f454492c3519498400c7b3f56569178b..911e0a4dd5e733d2bdcceb1a666ab2e245b12849 100644 (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)
index c48f7b8600dc15440e766c2f22af2acb38a8e95f..066ccbb38e6d33d8da1bda1a2557497f6438864f 100644 (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
+}