Beispiel #1
0
// genAppend generates constraints for a call to append.
func (a *analysis) genAppend(instr *ssa.Call, cgn *cgnode) {
	// Consider z = append(x, y).   y is optional.
	// This may allocate a new [1]T array; call its object w.
	// We get the following constraints:
	// 	z = x
	// 	z = &w
	//     *z = *y

	x := instr.Call.Args[0]

	z := instr
	a.copy(a.valueNode(z), a.valueNode(x), 1) // z = x

	if len(instr.Call.Args) == 1 {
		return // no allocation for z = append(x) or _ = append(x).
	}

	// TODO(adonovan): test append([]byte, ...string) []byte.

	y := instr.Call.Args[1]
	tArray := sliceToArray(instr.Call.Args[0].Type())

	var w nodeid
	w = a.nextNode()
	a.addNodes(tArray, "append")
	a.endObject(w, cgn, instr)

	a.copyElems(cgn, tArray.Elem(), z, y)        // *z = *y
	a.addressOf(instr.Type(), a.valueNode(z), w) //  z = &w
}
Beispiel #2
0
func (ctxt *context) callees(inst *ssa.Call) ([]*ssa.Function, error) {
	pos := ctxt.lprog.Fset.Position(inst.Pos())
	if pos.Line <= 0 {
		return nil, fmt.Errorf("no position")
	}
	qpos, err := oracle.ParseQueryPos(ctxt.lprog, posStr(pos), true)
	if err != nil {
		return nil, fmt.Errorf("cannot parse query pos %q: %v", posStr(pos), err)
	}
	result, err := ctxt.oracle.Query("callees", qpos)
	if err != nil {
		return nil, fmt.Errorf("query error: %v", err)
	}
	return calleeFuncs(result), nil
}