go/analysis/passes/cgocall: add typeparams test

This CL adds a test for the cgocall pass that involves use of generics.

Updates golang/go#48704

Change-Id: I521708d607c5f32ca24fe370b7d6436147bae6a5
Reviewed-on: https://go-review.googlesource.com/c/tools/+/358695
Run-TryBot: Zvonimir Pavlinovic <zpavlinovic@google.com>
gopls-CI: kokoro <noreply+kokoro@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Emmanuel Odeke <emmanuel@orijtech.com>
Reviewed-by: Robert Findley <rfindley@google.com>
Trust: Zvonimir Pavlinovic <zpavlinovic@google.com>
diff --git a/go/analysis/passes/cgocall/cgocall_test.go b/go/analysis/passes/cgocall/cgocall_test.go
index ba65426..45ca1da 100644
--- a/go/analysis/passes/cgocall/cgocall_test.go
+++ b/go/analysis/passes/cgocall/cgocall_test.go
@@ -9,9 +9,15 @@
 
 	"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 0000000..37e639a
--- /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
+}