Skip to content

Commit 725864d

Browse files
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 <[email protected]> Co-authored-by: Ayke <[email protected]>
1 parent fca2de2 commit 725864d

File tree

2 files changed

+81
-0
lines changed

2 files changed

+81
-0
lines changed

cgo/cgo.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -948,6 +948,9 @@ func (p *cgoPackage) isEquivalentAST(a, b ast.Node) bool {
948948
if !ok {
949949
return false
950950
}
951+
if node == nil || b == nil {
952+
return node == b
953+
}
951954
if len(node.List) != len(b.List) {
952955
return false
953956
}

cgo/cgo_test.go

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,84 @@ func TestCGo(t *testing.T) {
115115
}
116116
}
117117

118+
func Test_cgoPackage_isEquivalentAST(t *testing.T) {
119+
fieldA := &ast.Field{Type: &ast.BasicLit{Kind: token.STRING, Value: "a"}}
120+
fieldB := &ast.Field{Type: &ast.BasicLit{Kind: token.STRING, Value: "b"}}
121+
listOfFieldA := &ast.FieldList{List: []*ast.Field{fieldA}}
122+
listOfFieldB := &ast.FieldList{List: []*ast.Field{fieldB}}
123+
funcDeclA := &ast.FuncDecl{Name: &ast.Ident{Name: "a"}, Type: &ast.FuncType{Params: &ast.FieldList{}, Results: listOfFieldA}}
124+
funcDeclB := &ast.FuncDecl{Name: &ast.Ident{Name: "b"}, Type: &ast.FuncType{Params: &ast.FieldList{}, Results: listOfFieldB}}
125+
funcDeclNoResults := &ast.FuncDecl{Name: &ast.Ident{Name: "C"}, Type: &ast.FuncType{Params: &ast.FieldList{}}}
126+
127+
testCases := []struct {
128+
name string
129+
a, b ast.Node
130+
expected bool
131+
}{
132+
{
133+
name: "both nil",
134+
expected: true,
135+
},
136+
{
137+
name: "not same type",
138+
a: fieldA,
139+
b: &ast.FuncDecl{},
140+
expected: false,
141+
},
142+
{
143+
name: "Field same",
144+
a: fieldA,
145+
b: fieldA,
146+
expected: true,
147+
},
148+
{
149+
name: "Field different",
150+
a: fieldA,
151+
b: fieldB,
152+
expected: false,
153+
},
154+
{
155+
name: "FuncDecl Type Results nil",
156+
a: funcDeclNoResults,
157+
b: funcDeclNoResults,
158+
expected: true,
159+
},
160+
{
161+
name: "FuncDecl Type Results same",
162+
a: funcDeclA,
163+
b: funcDeclA,
164+
expected: true,
165+
},
166+
{
167+
name: "FuncDecl Type Results different",
168+
a: funcDeclA,
169+
b: funcDeclB,
170+
expected: false,
171+
},
172+
{
173+
name: "FuncDecl Type Results a nil",
174+
a: funcDeclNoResults,
175+
b: funcDeclB,
176+
expected: false,
177+
},
178+
{
179+
name: "FuncDecl Type Results b nil",
180+
a: funcDeclA,
181+
b: funcDeclNoResults,
182+
expected: false,
183+
},
184+
}
185+
186+
for _, tc := range testCases {
187+
t.Run(tc.name, func(t *testing.T) {
188+
p := &cgoPackage{}
189+
if got := p.isEquivalentAST(tc.a, tc.b); tc.expected != got {
190+
t.Errorf("expected %v, got %v", tc.expected, got)
191+
}
192+
})
193+
}
194+
}
195+
118196
// simpleImporter implements the types.Importer interface, but only allows
119197
// importing the unsafe package.
120198
type simpleImporter struct {

0 commit comments

Comments
 (0)