// genStaticCall generates constraints for a statically dispatched function call. func (a *analysis) genStaticCall(caller *cgnode, site *callsite, call *ssa.CallCommon, result nodeid) { fn := call.StaticCallee() // Special cases for inlined intrinsics. switch fn { case a.runtimeSetFinalizer: // Inline SetFinalizer so the call appears direct. site.targets = a.addOneNode(tInvalid, "SetFinalizer.targets", nil) a.addConstraint(&runtimeSetFinalizerConstraint{ targets: site.targets, x: a.valueNode(call.Args[0]), f: a.valueNode(call.Args[1]), }) return case a.reflectValueCall: // Inline (reflect.Value).Call so the call appears direct. dotdotdot := false ret := reflectCallImpl(a, caller, site, a.valueNode(call.Args[0]), a.valueNode(call.Args[1]), dotdotdot) if result != 0 { a.addressOf(fn.Signature.Results().At(0).Type(), result, ret) } return } // Ascertain the context (contour/cgnode) for a particular call. var obj nodeid if a.shouldUseContext(fn) { obj = a.makeFunctionObject(fn, site) // new contour } else { obj = a.objectNode(nil, fn) // shared contour } a.callEdge(caller, site, obj) sig := call.Signature() // Copy receiver, if any. params := a.funcParams(obj) args := call.Args if sig.Recv() != nil { sz := a.sizeof(sig.Recv().Type()) a.copy(params, a.valueNode(args[0]), sz) params += nodeid(sz) args = args[1:] } // Copy actual parameters into formal params block. // Must loop, since the actuals aren't contiguous. for i, arg := range args { sz := a.sizeof(sig.Params().At(i).Type()) a.copy(params, a.valueNode(arg), sz) params += nodeid(sz) } // Copy formal results block to actual result. if result != 0 { a.copy(result, a.funcResults(obj), a.sizeof(sig.Results())) } }