// callEdge is called for each edge in the callgraph. // calleeid is the callee's object node (has otFunction flag). // func (a *analysis) callEdge(caller *cgnode, site *callsite, calleeid nodeid) { obj := a.nodes[calleeid].obj if obj.flags&otFunction == 0 { panic(fmt.Sprintf("callEdge %s -> n%d: not a function object", site, calleeid)) } callee := obj.cgn if cg := a.result.CallGraph; cg != nil { // TODO(adonovan): opt: I would expect duplicate edges // (to wrappers) to arise due to the elimination of // context information, but I haven't observed any. // Understand this better. callgraph.AddEdge(cg.CreateNode(caller.fn), site.instr, cg.CreateNode(callee.fn)) } if a.log != nil { fmt.Fprintf(a.log, "\tcall edge %s -> %s\n", site, callee) } // Warn about calls to non-intrinsic external functions. // TODO(adonovan): de-dup these messages. if fn := callee.fn; fn.Blocks == nil && a.findIntrinsic(fn) == nil { a.warnf(site.pos(), "unsound call to unknown intrinsic: %s", fn) a.warnf(fn.Pos(), " (declared here)") } }
// callEdge is called for each edge in the callgraph. // calleeid is the callee's object node (has otFunction flag). // func (a *analysis) callEdge(caller *cgnode, site *callsite, calleeid nodeid) { obj := a.nodes[calleeid].obj if obj.flags&otFunction == 0 { panic(fmt.Sprintf("callEdge %s -> n%d: not a function object", site, calleeid)) } callee := obj.cgn if cg := a.result.CallGraph; cg != nil { callgraph.AddEdge(cg.CreateNode(caller.fn), site.instr, cg.CreateNode(callee.fn)) } if a.log != nil { fmt.Fprintf(a.log, "\tcall edge %s -> %s\n", site, callee) } // Warn about calls to non-intrinsic external functions. // TODO(adonovan): de-dup these messages. if fn := callee.fn; fn.Blocks == nil && a.findIntrinsic(fn) == nil { a.warnf(site.pos(), "unsound call to unknown intrinsic: %s", fn) a.warnf(fn.Pos(), " (declared here)") } }