Skip to content

Commit 656fcde

Browse files
John Dethridgetimothy-king
authored andcommitted
go/callgraph/vta: use core type for channels
When adding edges to the type graph for channel operations, we need the *types.Chan object for the channel's type. The underlying type of a channel may only be a type parameter, so use the core type instead to get the *types.Chan. Change-Id: I08078dbbb480363a372024161f0efb72a54c36a9 Reviewed-on: https://go-review.googlesource.com/c/tools/+/568735 Reviewed-by: Zvonimir Pavlinovic <[email protected]> Reviewed-by: Tim King <[email protected]> TryBot-Result: Gopher Robot <[email protected]> Run-TryBot: Tim King <[email protected]> LUCI-TryBot-Result: Go LUCI <[email protected]>
1 parent b3a5e0b commit 656fcde

File tree

3 files changed

+37
-3
lines changed

3 files changed

+37
-3
lines changed

go/callgraph/vta/graph.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -390,7 +390,7 @@ func (b *builder) unop(u *ssa.UnOp) {
390390
// Multiplication operator * is used here as a dereference operator.
391391
b.addInFlowAliasEdges(b.nodeFromVal(u), b.nodeFromVal(u.X))
392392
case token.ARROW:
393-
t := u.X.Type().Underlying().(*types.Chan).Elem()
393+
t := typeparams.CoreType(u.X.Type()).(*types.Chan).Elem()
394394
b.addInFlowAliasEdges(b.nodeFromVal(u), channelElem{typ: t})
395395
default:
396396
// There is no interesting type flow otherwise.
@@ -444,7 +444,7 @@ func (b *builder) fieldAddr(f *ssa.FieldAddr) {
444444
}
445445

446446
func (b *builder) send(s *ssa.Send) {
447-
t := s.Chan.Type().Underlying().(*types.Chan).Elem()
447+
t := typeparams.CoreType(s.Chan.Type()).(*types.Chan).Elem()
448448
b.addInFlowAliasEdges(channelElem{typ: t}, b.nodeFromVal(s.X))
449449
}
450450

@@ -458,7 +458,7 @@ func (b *builder) send(s *ssa.Send) {
458458
func (b *builder) selekt(s *ssa.Select) {
459459
recvIndex := 0
460460
for _, state := range s.States {
461-
t := state.Chan.Type().Underlying().(*types.Chan).Elem()
461+
t := typeparams.CoreType(state.Chan.Type()).(*types.Chan).Elem()
462462

463463
if state.Dir == types.SendOnly {
464464
b.addInFlowAliasEdges(channelElem{typ: t}, b.nodeFromVal(state.Send))

go/callgraph/vta/graph_test.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,7 @@ func TestVTAGraphConstruction(t *testing.T) {
181181
"testdata/src/store_load_alias.go",
182182
"testdata/src/phi_alias.go",
183183
"testdata/src/channels.go",
184+
"testdata/src/generic_channels.go",
184185
"testdata/src/select.go",
185186
"testdata/src/stores_arrays.go",
186187
"testdata/src/maps.go",
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
// Copyright 2021 The Go Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style
3+
// license that can be found in the LICENSE file.
4+
5+
// go:build ignore
6+
7+
package testdata
8+
9+
type I1 interface{}
10+
type I2 interface{}
11+
type I3 interface{}
12+
13+
func Foo[C interface{ ~chan I1 | ~chan<- I1 }](c C, j int) {
14+
c <- j
15+
}
16+
17+
func Bar[C interface{ ~chan I2 | ~<-chan I2 }](c C) {
18+
x := <-c
19+
print(x)
20+
}
21+
22+
func Baz[C interface{ ~chan I3 | ~<-chan I3 }](c C) {
23+
select {
24+
case x := <-c:
25+
print(x)
26+
default:
27+
}
28+
}
29+
30+
// WANT:
31+
// Local(t0) -> Channel(chan testdata.I1)
32+
// Channel(chan testdata.I2) -> Local(t0)
33+
// Channel(chan testdata.I3) -> Local(t0[2])

0 commit comments

Comments
 (0)