mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
cmd/cgo: avoid worklist nondeterminism.
+ Regression test. Fixes #9026. LGTM=rsc R=rsc CC=golang-codereviews https://golang.org/cl/162490043
This commit is contained in:
parent
f21a02a179
commit
09f6f05c1f
3 changed files with 49 additions and 9 deletions
|
|
@ -62,5 +62,6 @@ func Test8517(t *testing.T) { test8517(t) }
|
||||||
func Test8811(t *testing.T) { test8811(t) }
|
func Test8811(t *testing.T) { test8811(t) }
|
||||||
func TestReturnAfterGrow(t *testing.T) { testReturnAfterGrow(t) }
|
func TestReturnAfterGrow(t *testing.T) { testReturnAfterGrow(t) }
|
||||||
func TestReturnAfterGrowFromGo(t *testing.T) { testReturnAfterGrowFromGo(t) }
|
func TestReturnAfterGrowFromGo(t *testing.T) { testReturnAfterGrowFromGo(t) }
|
||||||
|
func Test9026(t *testing.T) { test9026(t) }
|
||||||
|
|
||||||
func BenchmarkCgoCall(b *testing.B) { benchCgoCall(b) }
|
func BenchmarkCgoCall(b *testing.B) { benchCgoCall(b) }
|
||||||
|
|
|
||||||
33
misc/cgo/test/issue9026.go
Normal file
33
misc/cgo/test/issue9026.go
Normal file
|
|
@ -0,0 +1,33 @@
|
||||||
|
package cgotest
|
||||||
|
|
||||||
|
/*
|
||||||
|
typedef struct {} git_merge_file_input;
|
||||||
|
|
||||||
|
typedef struct {} git_merge_file_options;
|
||||||
|
|
||||||
|
int git_merge_file(
|
||||||
|
git_merge_file_input *in,
|
||||||
|
git_merge_file_options *opts) {}
|
||||||
|
*/
|
||||||
|
import "C"
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func test9026(t *testing.T) {
|
||||||
|
var in C.git_merge_file_input
|
||||||
|
var opts *C.git_merge_file_options
|
||||||
|
C.git_merge_file(&in, opts)
|
||||||
|
|
||||||
|
// Test that the generated type names are deterministic.
|
||||||
|
// (Previously this would fail about 10% of the time.)
|
||||||
|
//
|
||||||
|
// Brittle: the assertion may fail spuriously when the algorithm
|
||||||
|
// changes, but should remain stable otherwise.
|
||||||
|
got := fmt.Sprintf("%T %T", in, opts)
|
||||||
|
want := "cgotest._Ctype_struct___12 *cgotest._Ctype_struct___13"
|
||||||
|
if got != want {
|
||||||
|
t.Errorf("Non-deterministic type names: got %s, want %s", got, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -944,6 +944,8 @@ type typeConv struct {
|
||||||
|
|
||||||
// Map from types to incomplete pointers to those types.
|
// Map from types to incomplete pointers to those types.
|
||||||
ptrs map[dwarf.Type][]*Type
|
ptrs map[dwarf.Type][]*Type
|
||||||
|
// Keys of ptrs in insertion order (deterministic worklist)
|
||||||
|
ptrKeys []dwarf.Type
|
||||||
|
|
||||||
// Predeclared types.
|
// Predeclared types.
|
||||||
bool ast.Expr
|
bool ast.Expr
|
||||||
|
|
@ -1061,16 +1063,17 @@ func (tr *TypeRepr) Set(repr string, fargs ...interface{}) {
|
||||||
func (c *typeConv) FinishType(pos token.Pos) {
|
func (c *typeConv) FinishType(pos token.Pos) {
|
||||||
// Completing one pointer type might produce more to complete.
|
// Completing one pointer type might produce more to complete.
|
||||||
// Keep looping until they're all done.
|
// Keep looping until they're all done.
|
||||||
for len(c.ptrs) > 0 {
|
for len(c.ptrKeys) > 0 {
|
||||||
for dtype := range c.ptrs {
|
dtype := c.ptrKeys[0]
|
||||||
// Note Type might invalidate c.ptrs[dtype].
|
c.ptrKeys = c.ptrKeys[1:]
|
||||||
t := c.Type(dtype, pos)
|
|
||||||
for _, ptr := range c.ptrs[dtype] {
|
// Note Type might invalidate c.ptrs[dtype].
|
||||||
ptr.Go.(*ast.StarExpr).X = t.Go
|
t := c.Type(dtype, pos)
|
||||||
ptr.C.Set("%s*", t.C)
|
for _, ptr := range c.ptrs[dtype] {
|
||||||
}
|
ptr.Go.(*ast.StarExpr).X = t.Go
|
||||||
delete(c.ptrs, dtype)
|
ptr.C.Set("%s*", t.C)
|
||||||
}
|
}
|
||||||
|
c.ptrs[dtype] = nil // retain the map key
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1237,6 +1240,9 @@ func (c *typeConv) Type(dtype dwarf.Type, pos token.Pos) *Type {
|
||||||
// Placeholder initialization; completed in FinishType.
|
// Placeholder initialization; completed in FinishType.
|
||||||
t.Go = &ast.StarExpr{}
|
t.Go = &ast.StarExpr{}
|
||||||
t.C.Set("<incomplete>*")
|
t.C.Set("<incomplete>*")
|
||||||
|
if _, ok := c.ptrs[dt.Type]; !ok {
|
||||||
|
c.ptrKeys = append(c.ptrKeys, dt.Type)
|
||||||
|
}
|
||||||
c.ptrs[dt.Type] = append(c.ptrs[dt.Type], t)
|
c.ptrs[dt.Type] = append(c.ptrs[dt.Type], t)
|
||||||
|
|
||||||
case *dwarf.QualType:
|
case *dwarf.QualType:
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue