// runPTA runs the pointer analysis of the selected SSA value or address. func runPTA(conf *pointer.Config, v ssa.Value, isAddr bool) (ptrs []pointerResult, err error) { T := v.Type() if isAddr { conf.AddIndirectQuery(v) T = deref(T) } else { conf.AddQuery(v) } ptares := ptrAnalysis(conf) var ptr pointer.Pointer if isAddr { ptr = ptares.IndirectQueries[v] } else { ptr = ptares.Queries[v] } if ptr == (pointer.Pointer{}) { return nil, fmt.Errorf("pointer analysis did not find expression (dead code?)") } pts := ptr.PointsTo() if pointer.CanHaveDynamicTypes(T) { // Show concrete types for interface/reflect.Value expression. if concs := pts.DynamicTypes(); concs.Len() > 0 { concs.Iterate(func(conc types.Type, pta interface{}) { labels := pta.(pointer.PointsToSet).Labels() sort.Sort(byPosAndString(labels)) // to ensure determinism ptrs = append(ptrs, pointerResult{conc, labels}) }) } } else { // Show labels for other expressions. labels := pts.Labels() sort.Sort(byPosAndString(labels)) // to ensure determinism ptrs = append(ptrs, pointerResult{T, labels}) } sort.Sort(byTypeString(ptrs)) // to ensure determinism return ptrs, nil }