Esempio n. 1
0
// 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
}