Ejemplo n.º 1
0
// genCall generates constraints for call instruction instr.
func (a *analysis) genCall(caller *cgnode, instr ssa.CallInstruction) {
	call := instr.Common()

	// Intrinsic implementations of built-in functions.
	if _, ok := call.Value.(*ssa.Builtin); ok {
		a.genBuiltinCall(instr, caller)
		return
	}

	var result nodeid
	if v := instr.Value(); v != nil {
		result = a.valueNode(v)
	}

	site := &callsite{instr: instr}
	if call.StaticCallee() != nil {
		a.genStaticCall(caller, site, call, result)
	} else if call.IsInvoke() {
		a.genInvoke(caller, site, call, result)
	} else {
		a.genDynamicCall(caller, site, call, result)
	}

	caller.sites = append(caller.sites, site)

	if a.log != nil {
		// TODO(adonovan): debug: improve log message.
		fmt.Fprintf(a.log, "\t%s to targets %s from %s\n", site, site.targets, caller)
	}
}
Ejemplo n.º 2
0
// addCallees adds client data and links for the facts that site calls fns.
func (a *analysis) addCallees(site ssa.CallInstruction, fns []*ssa.Function) {
	v := calleesJSON{
		Descr:   site.Common().Description(),
		Callees: []anchorJSON{}, // (JS wants non-nil)
	}
	var this *types.Package // for relativizing names
	if p := site.Parent().Package(); p != nil {
		this = p.Object
	}

	for _, fn := range fns {
		v.Callees = append(v.Callees, anchorJSON{
			Text: prettyFunc(this, fn),
			Href: a.posURL(funcToken(fn), len("func")),
		})
	}

	fi, offset := a.fileAndOffset(site.Common().Pos())
	fi.addLink(aLink{
		start:   offset,
		end:     offset + len("("),
		title:   fmt.Sprintf("%d callees", len(v.Callees)),
		onclick: fmt.Sprintf("onClickCallees(%d)", fi.addData(v)),
	})
}
Ejemplo n.º 3
0
// genBuiltinCall generates contraints for a call to a built-in.
func (a *analysis) genBuiltinCall(instr ssa.CallInstruction, cgn *cgnode) {
	call := instr.Common()
	switch call.Value.(*ssa.Builtin).Name() {
	case "append":
		// Safe cast: append cannot appear in a go or defer statement.
		a.genAppend(instr.(*ssa.Call), cgn)

	case "copy":
		tElem := call.Args[0].Type().Underlying().(*types.Slice).Elem()
		a.copyElems(cgn, tElem, call.Args[0], call.Args[1])

	case "panic":
		a.copy(a.panicNode, a.valueNode(call.Args[0]), 1)

	case "recover":
		if v := instr.Value(); v != nil {
			a.copy(a.valueNode(v), a.panicNode, 1)
		}

	case "print":
		// In the tests, the probe might be the sole reference
		// to its arg, so make sure we create nodes for it.
		a.valueNode(call.Args[0])

	case "ssa:wrapnilchk":
		a.copy(a.valueNode(instr.Value()), a.valueNode(call.Args[0]), 1)

	default:
		// No-ops: close len cap real imag complex print println delete.
	}
}