| // 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. |
| |
| // go:build ignore |
| |
| package testdata |
| |
| // TestNodeTypeUniqueness checks if semantically equivalent types |
| // are being represented using the same pointer value in vta nodes. |
| // If not, some edges become missing in the string representation |
| // of the graph. |
| |
| type I interface { |
| Foo() |
| } |
| |
| type A struct{} |
| |
| func (a A) Foo() {} |
| |
| func Baz(a *A) (I, I, interface{}, interface{}) { |
| var i I |
| i = a |
| |
| var ii I |
| aa := &A{} |
| ii = aa |
| |
| m := make(map[int]int) |
| var iii interface{} |
| iii = m |
| |
| var iiii interface{} |
| iiii = m |
| |
| return i, ii, iii, iiii |
| } |
| |
| // Relevant SSA: |
| // func Baz(a *A) (I, I, interface{}, interface{}): |
| // t0 = make I <- *A (a) |
| // t1 = new A (complit) |
| // t2 = make I <- *A (t1) |
| // t3 = make map[int]int |
| // t4 = make interface{} <- map[int]int (t3) |
| // t5 = make interface{} <- map[int]int (t3) |
| // return t0, t2, t4, t5 |
| |
| // Without canon approach, one of Pointer(*A) -> Local(t0) and Pointer(*A) -> Local(t2) edges is |
| // missing in the graph string representation. The original graph has both of the edges but the |
| // source node Pointer(*A) is not the same; two occurrences of Pointer(*A) are considered separate |
| // nodes. Since they have the same string representation, one edge gets overridden by the other |
| // during the graph stringification, instead of being joined together as in below. |
| |
| // WANT: |
| // Pointer(*testdata.A) -> Local(t0), Local(t2) |
| // Local(t3) -> Local(t4), Local(t5) |