Search in sources :

Example 1 with NullnessAnalysis

use of soot.jimple.toolkits.annotation.nullcheck.NullnessAnalysis in project soot by Sable.

the class OnFlyCallGraphBuilder method addInvokeCallSite.

/*
	 * How type based reflection resolution works:
	 *
	 * In general, for each call to invoke(), we record the local of the receiver
	 * argument and the argument array. Whenever a new type is added to the points
	 * to set of the receiver argument we add that type to the reachingBaseTypes and
	 * try to resolve the reflective method call (see addType, addBaseType, and
	 * updatedNode() in OnFlyCallGraph).
	 *
	 * For added precision, we also record the second argument to invoke. If it is
	 * always null, this means the invoke() call resolves only to nullary methods.
	 *
	 * When the second argument is a variable that must not be null we can narrow
	 * down the called method based on the possible sizes of the argument array and
	 * the types it contains. Whenever a new allocation reaches this variable we
	 * record the possible size of the array (by looking at the allocation site) and
	 * the possible types stored in the array (see updatedNode in OnFlyCallGraph in
	 * the branch wantInvokeArg()). If the size of the array isn't statically known,
	 * the analysis considers methods of all possible arities. In addition, we track
	 * the PAG node corresponding to the array contents. If a new type reaches this
	 * node, we update the possible argument types. (see propagate() in PropWorklist
	 * and the visitor, and updatedFieldRef in OnFlyCallGraph).
	 *
	 * For details on the method resolution process, see resolveInvoke()
	 *
	 * Finally, for cases like o.invoke(b, foo, bar, baz); it is very easy to
	 * statically determine precisely which types are in which argument positions.
	 * This is computed using the ConstantArrayAnalysis and are resolved using
	 * resolveStaticTypes().
	 */
private void addInvokeCallSite(Stmt s, SootMethod container, InstanceInvokeExpr d) {
    Local l = (Local) d.getArg(0);
    Value argArray = d.getArg(1);
    InvokeCallSite ics;
    if (argArray instanceof NullConstant) {
        ics = new InvokeCallSite(s, container, d, l);
    } else {
        if (analysisKey != container) {
            ExceptionalUnitGraph graph = new ExceptionalUnitGraph(container.getActiveBody());
            nullnessCache = new NullnessAnalysis(graph);
            arrayCache = new ConstantArrayAnalysis(graph, container.getActiveBody());
            analysisKey = container;
        }
        Local argLocal = (Local) argArray;
        int nullnessCode;
        if (nullnessCache.isAlwaysNonNullBefore(s, argLocal)) {
            nullnessCode = InvokeCallSite.MUST_NOT_BE_NULL;
        } else if (nullnessCache.isAlwaysNullBefore(s, argLocal)) {
            nullnessCode = InvokeCallSite.MUST_BE_NULL;
        } else {
            nullnessCode = InvokeCallSite.MAY_BE_NULL;
        }
        if (nullnessCode != InvokeCallSite.MUST_BE_NULL && arrayCache.isConstantBefore(s, argLocal)) {
            ArrayTypes reachingArgTypes = arrayCache.getArrayTypesBefore(s, argLocal);
            if (nullnessCode == InvokeCallSite.MAY_BE_NULL) {
                reachingArgTypes.possibleSizes.add(0);
            }
            ics = new InvokeCallSite(s, container, d, l, reachingArgTypes, nullnessCode);
        } else {
            ics = new InvokeCallSite(s, container, d, l, argLocal, nullnessCode);
            invokeArgsToInvokeSite.put(argLocal, ics);
        }
    }
    baseToInvokeSite.put(l, ics);
}
Also used : ExceptionalUnitGraph(soot.toolkits.graph.ExceptionalUnitGraph) ArrayTypes(soot.jimple.toolkits.callgraph.ConstantArrayAnalysis.ArrayTypes) Value(soot.Value) Local(soot.Local) NullConstant(soot.jimple.NullConstant) NullnessAnalysis(soot.jimple.toolkits.annotation.nullcheck.NullnessAnalysis)

Aggregations

Local (soot.Local)1 Value (soot.Value)1 NullConstant (soot.jimple.NullConstant)1 NullnessAnalysis (soot.jimple.toolkits.annotation.nullcheck.NullnessAnalysis)1 ArrayTypes (soot.jimple.toolkits.callgraph.ConstantArrayAnalysis.ArrayTypes)1 ExceptionalUnitGraph (soot.toolkits.graph.ExceptionalUnitGraph)1