Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
cmd/compile: copy blank parameter node when substituting function type
When a function type is copied (e.g. for substituting type parameters), we make copies of its parameter ir.Name nodes, so they are not shared with the old function type. But currently a blank (_) identifier is not copied but shared. The parameter node's frame offset is assigned (in ABI analysis) and then used in the concurrent backend. Shared node can cause a data race. Make a new blank parameter node to avoid sharing. (Unified IR does already not have this problem. This fixes non-unified-IR mode.) This seems to fix golang#55357. Change-Id: Ie27f08e5589ac7d5d3f0d0d5de1a21e4fd2765c9 Reviewed-on: https://go-review.googlesource.com/c/go/+/443158 Reviewed-by: Keith Randall <khr@golang.org> Run-TryBot: Cherry Mui <cherryyz@google.com> TryBot-Result: Gopher Robot <gobot@golang.org> Reviewed-by: Keith Randall <khr@google.com>
- Loading branch information
Showing
2 changed files
with
73 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
// Copyright 2022 The Go Authors. All rights reserved. | ||
// Use of this source code is governed by a BSD-style | ||
// license that can be found in the LICENSE file. | ||
|
||
//go:build !compiler_bootstrap | ||
|
||
package test | ||
|
||
// The racecompile builder only builds packages, but does not build | ||
// or run tests. This is a non-test file to hold cases that (used | ||
// to) trigger compiler data races, so they will be exercised on | ||
// the racecompile builder. | ||
// | ||
// This package is not imported so functions here are not included | ||
// in the actual compiler. | ||
|
||
// Issue 55357: data race when building multiple instantiations of | ||
// generic closures with _ parameters. | ||
func Issue55357() { | ||
type U struct { | ||
A int | ||
B string | ||
C string | ||
} | ||
var q T55357[U] | ||
q.Count() | ||
q.List() | ||
|
||
type M struct { | ||
A int64 | ||
B uint32 | ||
C uint32 | ||
} | ||
var q2 T55357[M] | ||
q2.Count() | ||
q2.List() | ||
} | ||
|
||
type T55357[T any] struct{} | ||
|
||
//go:noinline | ||
func (q *T55357[T]) do(w, v bool, fn func(bk []byte, v T) error) error { | ||
return nil | ||
} | ||
|
||
func (q *T55357[T]) Count() (n int, rerr error) { | ||
err := q.do(false, false, func(kb []byte, _ T) error { | ||
n++ | ||
return nil | ||
}) | ||
return n, err | ||
} | ||
|
||
func (q *T55357[T]) List() (list []T, rerr error) { | ||
var l []T | ||
err := q.do(false, true, func(_ []byte, v T) error { | ||
l = append(l, v) | ||
return nil | ||
}) | ||
if err != nil { | ||
return nil, err | ||
} | ||
return l, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters