diff --git a/go/analysis/passes/cgocall/cgocall_test.go b/go/analysis/passes/cgocall/cgocall_test.go index ba654261c9..45ca1da8b1 100644 --- a/go/analysis/passes/cgocall/cgocall_test.go +++ b/go/analysis/passes/cgocall/cgocall_test.go @@ -9,9 +9,15 @@ import ( "golang.org/x/tools/go/analysis/analysistest" "golang.org/x/tools/go/analysis/passes/cgocall" + "golang.org/x/tools/internal/typeparams" ) func Test(t *testing.T) { testdata := analysistest.TestData() - analysistest.Run(t, testdata, cgocall.Analyzer, "a", "b", "c") + tests := []string{"a", "b", "c"} + if typeparams.Enabled { + // and testdata/src/typeparams/typeparams.go when possible + tests = append(tests, "typeparams") + } + analysistest.Run(t, testdata, cgocall.Analyzer, tests...) } diff --git a/go/analysis/passes/cgocall/testdata/src/typeparams/typeparams.go b/go/analysis/passes/cgocall/testdata/src/typeparams/typeparams.go new file mode 100644 index 0000000000..37e639aead --- /dev/null +++ b/go/analysis/passes/cgocall/testdata/src/typeparams/typeparams.go @@ -0,0 +1,37 @@ +// Copyright 2021 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. + +// This file contains tests for the cgo checker. + +package a + +// void f(void *ptr) {} +import "C" + +import "unsafe" + +func CgoTest[T any]() { + var c chan bool + C.f(*(*unsafe.Pointer)(unsafe.Pointer(&c))) // want "embedded pointer" + C.f(unsafe.Pointer(&c)) // want "embedded pointer" + + var schan S[chan bool] + C.f(*(*unsafe.Pointer)(unsafe.Pointer(&schan))) // want "embedded pointer" + C.f(unsafe.Pointer(&schan)) // want "embedded pointer" + + var x T + C.f(*(*unsafe.Pointer)(unsafe.Pointer(&x))) // no findings as T is not known compile-time + C.f(unsafe.Pointer(&x)) + + // instantiating CgoTest should not yield any warnings + CgoTest[chan bool]() + + var sint S[int] + C.f(*(*unsafe.Pointer)(unsafe.Pointer(&sint))) + C.f(unsafe.Pointer(&sint)) +} + +type S[X any] struct { + val X +}