From 2eafbb8878ffc5a032fdc9361ed75731da5bb698 Mon Sep 17 00:00:00 2001 From: Russ Cox Date: Sun, 3 Feb 2013 01:18:28 -0500 Subject: [PATCH] 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 --- src/cmd/gc/walk.c | 6 +++++- .../runtime/race/testdata/regression_test.go | 18 ++++++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) 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 +} -- 2.48.1