cgo: fixes panic when FuncType.Results is nil (#3136)

* cgo: fixes panic when FuncType.Results is nil

FuncType.Results can be nil. This fixes the comparison and backfills
relevant tests.

Signed-off-by: Adrian Cole <adrian@tetrate.io>
Co-authored-by: Ayke <aykevanlaethem@gmail.com>
Этот коммит содержится в:
Crypt Keeper 2022-09-27 01:08:23 +08:00 коммит произвёл GitHub
родитель fca2de21b1
коммит 725864d8dc
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
2 изменённых файлов: 81 добавлений и 0 удалений

Просмотреть файл

@ -948,6 +948,9 @@ func (p *cgoPackage) isEquivalentAST(a, b ast.Node) bool {
if !ok {
return false
}
if node == nil || b == nil {
return node == b
}
if len(node.List) != len(b.List) {
return false
}

Просмотреть файл

@ -115,6 +115,84 @@ func TestCGo(t *testing.T) {
}
}
func Test_cgoPackage_isEquivalentAST(t *testing.T) {
fieldA := &ast.Field{Type: &ast.BasicLit{Kind: token.STRING, Value: "a"}}
fieldB := &ast.Field{Type: &ast.BasicLit{Kind: token.STRING, Value: "b"}}
listOfFieldA := &ast.FieldList{List: []*ast.Field{fieldA}}
listOfFieldB := &ast.FieldList{List: []*ast.Field{fieldB}}
funcDeclA := &ast.FuncDecl{Name: &ast.Ident{Name: "a"}, Type: &ast.FuncType{Params: &ast.FieldList{}, Results: listOfFieldA}}
funcDeclB := &ast.FuncDecl{Name: &ast.Ident{Name: "b"}, Type: &ast.FuncType{Params: &ast.FieldList{}, Results: listOfFieldB}}
funcDeclNoResults := &ast.FuncDecl{Name: &ast.Ident{Name: "C"}, Type: &ast.FuncType{Params: &ast.FieldList{}}}
testCases := []struct {
name string
a, b ast.Node
expected bool
}{
{
name: "both nil",
expected: true,
},
{
name: "not same type",
a: fieldA,
b: &ast.FuncDecl{},
expected: false,
},
{
name: "Field same",
a: fieldA,
b: fieldA,
expected: true,
},
{
name: "Field different",
a: fieldA,
b: fieldB,
expected: false,
},
{
name: "FuncDecl Type Results nil",
a: funcDeclNoResults,
b: funcDeclNoResults,
expected: true,
},
{
name: "FuncDecl Type Results same",
a: funcDeclA,
b: funcDeclA,
expected: true,
},
{
name: "FuncDecl Type Results different",
a: funcDeclA,
b: funcDeclB,
expected: false,
},
{
name: "FuncDecl Type Results a nil",
a: funcDeclNoResults,
b: funcDeclB,
expected: false,
},
{
name: "FuncDecl Type Results b nil",
a: funcDeclA,
b: funcDeclNoResults,
expected: false,
},
}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
p := &cgoPackage{}
if got := p.isEquivalentAST(tc.a, tc.b); tc.expected != got {
t.Errorf("expected %v, got %v", tc.expected, got)
}
})
}
}
// simpleImporter implements the types.Importer interface, but only allows
// importing the unsafe package.
type simpleImporter struct {