Search in sources :

Example 6 with NullType

use of soot.NullType in project soot by Sable.

the class DeadAssignmentEliminator method internalTransform.

/**
 * Eliminates dead code in a linear fashion.  Complexity is linear
 * with respect to the statements.
 *
 * Does not work on grimp code because of the check on the right hand
 * side for side effects.
 */
@Override
protected void internalTransform(Body b, String phaseName, Map<String, String> options) {
    boolean eliminateOnlyStackLocals = PhaseOptions.getBoolean(options, "only-stack-locals");
    final Options soptions = Options.v();
    if (soptions.verbose()) {
        logger.debug("[" + b.getMethod().getName() + "] Eliminating dead code...");
    }
    if (soptions.time()) {
        Timers.v().deadCodeTimer.start();
    }
    Chain<Unit> units = b.getUnits();
    Deque<Unit> q = new ArrayDeque<Unit>(units.size());
    // Make a first pass through the statements, noting
    // the statements we must absolutely keep.
    boolean isStatic = b.getMethod().isStatic();
    boolean allEssential = true;
    boolean checkInvoke = false;
    Local thisLocal = null;
    for (Iterator<Unit> it = units.iterator(); it.hasNext(); ) {
        Unit s = it.next();
        boolean isEssential = true;
        if (s instanceof NopStmt) {
            // Hack: do not remove nop if is is used for a Trap
            // which is at the very end of the code.
            boolean removeNop = it.hasNext();
            if (!removeNop) {
                removeNop = true;
                for (Trap t : b.getTraps()) {
                    if (t.getEndUnit() == s) {
                        removeNop = false;
                        break;
                    }
                }
            }
            if (removeNop) {
                it.remove();
                continue;
            }
        } else if (s instanceof AssignStmt) {
            AssignStmt as = (AssignStmt) s;
            Value lhs = as.getLeftOp();
            Value rhs = as.getRightOp();
            // Stmt is of the form a = a which is useless
            if (lhs == rhs && lhs instanceof Local) {
                it.remove();
                continue;
            }
            if (lhs instanceof Local && (!eliminateOnlyStackLocals || ((Local) lhs).getName().startsWith("$") || lhs.getType() instanceof NullType)) {
                isEssential = false;
                if (!checkInvoke) {
                    checkInvoke = as.containsInvokeExpr();
                }
                if (rhs instanceof CastExpr) {
                    // CastExpr          : can trigger ClassCastException, but null-casts never fail
                    CastExpr ce = (CastExpr) rhs;
                    Type t = ce.getCastType();
                    Value v = ce.getOp();
                    isEssential = !(v instanceof NullConstant && t instanceof RefType);
                } else if (rhs instanceof InvokeExpr || rhs instanceof ArrayRef || rhs instanceof NewExpr || rhs instanceof NewArrayExpr || rhs instanceof NewMultiArrayExpr) {
                    // ArrayRef          : can have side effects (like throwing a null pointer exception)
                    // InvokeExpr        : can have side effects (like throwing a null pointer exception)
                    // NewArrayExpr      : can throw exception
                    // NewMultiArrayExpr : can throw exception
                    // NewExpr           : can trigger class initialization
                    isEssential = true;
                } else if (rhs instanceof FieldRef) {
                    // Can trigger class initialization
                    isEssential = true;
                    if (rhs instanceof InstanceFieldRef) {
                        InstanceFieldRef ifr = (InstanceFieldRef) rhs;
                        if (!isStatic && thisLocal == null) {
                            thisLocal = b.getThisLocal();
                        }
                        // Any InstanceFieldRef may have side effects,
                        // unless the base is reading from 'this'
                        // in a non-static method
                        isEssential = (isStatic || thisLocal != ifr.getBase());
                    }
                } else if (rhs instanceof DivExpr || rhs instanceof RemExpr) {
                    BinopExpr expr = (BinopExpr) rhs;
                    Type t1 = expr.getOp1().getType();
                    Type t2 = expr.getOp2().getType();
                    // Can trigger a division by zero
                    boolean t2Int = t2 instanceof IntType;
                    isEssential = t2Int || t1 instanceof IntType || t1 instanceof LongType || t2 instanceof LongType || t1 instanceof UnknownType || t2 instanceof UnknownType;
                    if (isEssential && t2Int) {
                        Value v = expr.getOp2();
                        if (v instanceof IntConstant) {
                            IntConstant i = (IntConstant) v;
                            isEssential = (i.value == 0);
                        } else
                            // could be 0, we don't know
                            isEssential = true;
                    }
                    if (isEssential && t2 instanceof LongType) {
                        Value v = expr.getOp2();
                        if (v instanceof LongConstant) {
                            LongConstant l = (LongConstant) v;
                            isEssential = (l.value == 0);
                        } else
                            // could be 0, we don't know
                            isEssential = true;
                    }
                }
            }
        }
        if (isEssential) {
            q.addFirst(s);
        }
        allEssential &= isEssential;
    }
    if (checkInvoke || !allEssential) {
        // Add all the statements which are used to compute values
        // for the essential statements, recursively
        final LocalDefs localDefs = LocalDefs.Factory.newLocalDefs(b);
        if (!allEssential) {
            Set<Unit> essential = new HashSet<Unit>(b.getUnits().size());
            while (!q.isEmpty()) {
                Unit s = q.removeFirst();
                if (essential.add(s)) {
                    for (ValueBox box : s.getUseBoxes()) {
                        Value v = box.getValue();
                        if (v instanceof Local) {
                            Local l = (Local) v;
                            List<Unit> defs = localDefs.getDefsOfAt(l, s);
                            if (defs != null)
                                q.addAll(defs);
                        }
                    }
                }
            }
            // Remove the dead statements
            units.retainAll(essential);
        }
        if (checkInvoke) {
            final LocalUses localUses = LocalUses.Factory.newLocalUses(b, localDefs);
            // Eliminate dead assignments from invokes such as x = f(), where
            // x is no longer used
            List<AssignStmt> postProcess = new ArrayList<AssignStmt>();
            for (Unit u : units) {
                if (u instanceof AssignStmt) {
                    AssignStmt s = (AssignStmt) u;
                    if (s.containsInvokeExpr()) {
                        // Just find one use of l which is essential
                        boolean deadAssignment = true;
                        for (UnitValueBoxPair pair : localUses.getUsesOf(s)) {
                            if (units.contains(pair.unit)) {
                                deadAssignment = false;
                                break;
                            }
                        }
                        if (deadAssignment) {
                            postProcess.add(s);
                        }
                    }
                }
            }
            final Jimple jimple = Jimple.v();
            for (AssignStmt s : postProcess) {
                // Transform it into a simple invoke.
                Stmt newInvoke = jimple.newInvokeStmt(s.getInvokeExpr());
                newInvoke.addAllTagsOf(s);
                units.swapWith(s, newInvoke);
                // If we have a callgraph, we need to fix it
                if (Scene.v().hasCallGraph())
                    Scene.v().getCallGraph().swapEdgesOutOf(s, newInvoke);
            }
        }
    }
    if (soptions.time()) {
        Timers.v().deadCodeTimer.end();
    }
}
Also used : Options(soot.options.Options) PhaseOptions(soot.PhaseOptions) LongType(soot.LongType) AssignStmt(soot.jimple.AssignStmt) NewMultiArrayExpr(soot.jimple.NewMultiArrayExpr) ArrayList(java.util.ArrayList) Unit(soot.Unit) IntType(soot.IntType) NopStmt(soot.jimple.NopStmt) AssignStmt(soot.jimple.AssignStmt) Stmt(soot.jimple.Stmt) RefType(soot.RefType) ArrayRef(soot.jimple.ArrayRef) InvokeExpr(soot.jimple.InvokeExpr) CastExpr(soot.jimple.CastExpr) InstanceFieldRef(soot.jimple.InstanceFieldRef) IntConstant(soot.jimple.IntConstant) UnitValueBoxPair(soot.toolkits.scalar.UnitValueBoxPair) HashSet(java.util.HashSet) LongConstant(soot.jimple.LongConstant) FieldRef(soot.jimple.FieldRef) InstanceFieldRef(soot.jimple.InstanceFieldRef) Local(soot.Local) NullConstant(soot.jimple.NullConstant) Trap(soot.Trap) LocalUses(soot.toolkits.scalar.LocalUses) LocalDefs(soot.toolkits.scalar.LocalDefs) ArrayDeque(java.util.ArrayDeque) UnknownType(soot.UnknownType) RefType(soot.RefType) Type(soot.Type) UnknownType(soot.UnknownType) IntType(soot.IntType) LongType(soot.LongType) NullType(soot.NullType) DivExpr(soot.jimple.DivExpr) NewArrayExpr(soot.jimple.NewArrayExpr) NopStmt(soot.jimple.NopStmt) RemExpr(soot.jimple.RemExpr) ValueBox(soot.ValueBox) Value(soot.Value) NewExpr(soot.jimple.NewExpr) Jimple(soot.jimple.Jimple) NullType(soot.NullType) BinopExpr(soot.jimple.BinopExpr)

Example 7 with NullType

use of soot.NullType in project soot by Sable.

the class OnFlyCallGraphBuilder method resolveInvoke.

private void resolveInvoke(Collection<InvokeCallSite> list) {
    for (InvokeCallSite ics : list) {
        Set<Type> s = reachingBaseTypes.get(ics.base());
        if (s == null || s.isEmpty()) {
            continue;
        }
        if (ics.reachingTypes() != null) {
            assert ics.nullnessCode() != InvokeCallSite.MUST_BE_NULL;
            resolveStaticTypes(s, ics);
            continue;
        }
        boolean mustNotBeNull = ics.nullnessCode() == InvokeCallSite.MUST_NOT_BE_NULL;
        boolean mustBeNull = ics.nullnessCode() == InvokeCallSite.MUST_BE_NULL;
        // yet, then generate nullary methods
        if (mustBeNull || (ics.nullnessCode() == InvokeCallSite.MAY_BE_NULL && (!invokeArgsToSize.containsKey(ics.argArray()) || !reachingArgTypes.containsKey(ics.argArray())))) {
            for (Type bType : s) {
                assert bType instanceof RefType;
                SootClass baseClass = ((RefType) bType).getSootClass();
                assert !baseClass.isInterface();
                Iterator<SootMethod> mIt = getPublicNullaryMethodIterator(baseClass);
                while (mIt.hasNext()) {
                    SootMethod sm = mIt.next();
                    cm.addVirtualEdge(ics.container(), ics.stmt(), sm, Kind.REFL_INVOKE, null);
                }
            }
        } else {
            /*
				 * In this branch, either the invoke arg must not be null, or may be null and we
				 * have size and type information. Invert the above condition: ~mustBeNull &&
				 * (~mayBeNull || (has-size && has-type)) => (~mustBeNull && ~mayBeNull) ||
				 * (~mustBeNull && has-size && has-type) => mustNotBeNull || (~mustBeNull &&
				 * has-types && has-size) => mustNotBeNull || (mayBeNull && has-types &&
				 * has-size)
				 */
            Set<Type> reachingTypes = reachingArgTypes.get(ics.argArray());
            /*
				 * the path condition allows must-not-be null without type and size info. Do
				 * nothing in this case. THIS IS UNSOUND if default null values in an argument
				 * array are used.
				 */
            if (reachingTypes == null || !invokeArgsToSize.containsKey(ics.argArray())) {
                assert ics.nullnessCode() == InvokeCallSite.MUST_NOT_BE_NULL : ics;
                return;
            }
            assert reachingTypes != null && invokeArgsToSize.containsKey(ics.argArray());
            BitSet methodSizes = invokeArgsToSize.get(ics.argArray());
            for (Type bType : s) {
                assert bType instanceof RefLikeType;
                // we do not handle static methods or array reflection
                if (bType instanceof NullType || bType instanceof ArrayType) {
                    continue;
                } else {
                    SootClass baseClass = ((RefType) bType).getSootClass();
                    Iterator<SootMethod> mIt = getPublicMethodIterator(baseClass, reachingTypes, methodSizes, mustNotBeNull);
                    while (mIt.hasNext()) {
                        SootMethod sm = mIt.next();
                        cm.addVirtualEdge(ics.container(), ics.stmt(), sm, Kind.REFL_INVOKE, null);
                    }
                }
            }
        }
    }
}
Also used : RefType(soot.RefType) RefLikeType(soot.RefLikeType) ArrayType(soot.ArrayType) RefType(soot.RefType) ShortType(soot.ShortType) BooleanType(soot.BooleanType) ByteType(soot.ByteType) Type(soot.Type) DoubleType(soot.DoubleType) FloatType(soot.FloatType) IntType(soot.IntType) CharType(soot.CharType) LongType(soot.LongType) NullType(soot.NullType) RefLikeType(soot.RefLikeType) ArrayType(soot.ArrayType) PrimType(soot.PrimType) BitSet(java.util.BitSet) SootMethod(soot.SootMethod) NullType(soot.NullType) SootClass(soot.SootClass)

Example 8 with NullType

use of soot.NullType in project soot by Sable.

the class CopyPropagator method internalTransform.

/**
 * Cascaded copy propagator.
 *
 * If it encounters situations of the form: A: a = ...; B: ... x = a; C:...
 * use (x); where a has only one definition, and x has only one definition
 * (B), then it can propagate immediately without checking between B and C
 * for redefinitions of a (namely) A because they cannot occur. In this case
 * the propagator is global.
 *
 * Otherwise, if a has multiple definitions then it only checks for
 * redefinitions of Propagates constants and copies in extended basic
 * blocks.
 *
 * Does not propagate stack locals when the "only-regular-locals" option is
 * true.
 */
protected void internalTransform(Body b, String phaseName, Map<String, String> opts) {
    CPOptions options = new CPOptions(opts);
    StmtBody stmtBody = (StmtBody) b;
    int fastCopyPropagationCount = 0;
    int slowCopyPropagationCount = 0;
    if (Options.v().verbose())
        logger.debug("[" + stmtBody.getMethod().getName() + "] Propagating copies...");
    if (Options.v().time())
        Timers.v().propagatorTimer.start();
    Chain<Unit> units = stmtBody.getUnits();
    Map<Local, Integer> localToDefCount = new HashMap<Local, Integer>();
    // Count number of definitions for each local.
    for (Unit u : units) {
        Stmt s = (Stmt) u;
        if (s instanceof DefinitionStmt && ((DefinitionStmt) s).getLeftOp() instanceof Local) {
            Local l = (Local) ((DefinitionStmt) s).getLeftOp();
            if (!localToDefCount.containsKey(l))
                localToDefCount.put(l, new Integer(1));
            else
                localToDefCount.put(l, new Integer(localToDefCount.get(l).intValue() + 1));
        }
    }
    if (throwAnalysis == null)
        throwAnalysis = Scene.v().getDefaultThrowAnalysis();
    if (forceOmitExceptingUnitEdges == false)
        forceOmitExceptingUnitEdges = Options.v().omit_excepting_unit_edges();
    // Go through the definitions, building the webs
    UnitGraph graph = new ExceptionalUnitGraph(stmtBody, throwAnalysis, forceOmitExceptingUnitEdges);
    LocalDefs localDefs = LocalDefs.Factory.newLocalDefs(graph);
    // Perform a local propagation pass.
    {
        Iterator<Unit> stmtIt = (new PseudoTopologicalOrderer<Unit>()).newList(graph, false).iterator();
        while (stmtIt.hasNext()) {
            Stmt stmt = (Stmt) stmtIt.next();
            for (ValueBox useBox : stmt.getUseBoxes()) {
                if (useBox.getValue() instanceof Local) {
                    Local l = (Local) useBox.getValue();
                    // null due to typing, we always inline that constant.
                    if (!(l.getType() instanceof NullType)) {
                        if (options.only_regular_locals() && l.getName().startsWith("$"))
                            continue;
                        if (options.only_stack_locals() && !l.getName().startsWith("$"))
                            continue;
                    }
                    List<Unit> defsOfUse = localDefs.getDefsOfAt(l, stmt);
                    // We can propagate the definition if we either only
                    // have
                    // one definition or all definitions are side-effect
                    // free
                    // and equal. For starters, we only support constants in
                    // the case of multiple definitions.
                    boolean propagateDef = defsOfUse.size() == 1;
                    if (!propagateDef && defsOfUse.size() > 0) {
                        boolean agrees = true;
                        Constant constVal = null;
                        for (Unit defUnit : defsOfUse) {
                            boolean defAgrees = false;
                            if (defUnit instanceof AssignStmt) {
                                AssignStmt assign = (AssignStmt) defUnit;
                                if (assign.getRightOp() instanceof Constant) {
                                    if (constVal == null) {
                                        constVal = (Constant) assign.getRightOp();
                                        defAgrees = true;
                                    } else if (constVal.equals(assign.getRightOp()))
                                        defAgrees = true;
                                }
                            }
                            agrees &= defAgrees;
                        }
                        propagateDef = agrees;
                    }
                    if (propagateDef) {
                        DefinitionStmt def = (DefinitionStmt) defsOfUse.get(0);
                        if (def.getRightOp() instanceof Constant) {
                            if (useBox.canContainValue(def.getRightOp())) {
                                useBox.setValue(def.getRightOp());
                            }
                        } else if (def.getRightOp() instanceof CastExpr) {
                            CastExpr ce = (CastExpr) def.getRightOp();
                            if (ce.getCastType() instanceof RefLikeType) {
                                boolean isConstNull = ce.getOp() instanceof IntConstant && ((IntConstant) ce.getOp()).value == 0;
                                isConstNull |= ce.getOp() instanceof LongConstant && ((LongConstant) ce.getOp()).value == 0;
                                if (isConstNull) {
                                    if (useBox.canContainValue(NullConstant.v())) {
                                        useBox.setValue(NullConstant.v());
                                    }
                                }
                            }
                        } else if (def.getRightOp() instanceof Local) {
                            Local m = (Local) def.getRightOp();
                            if (l != m) {
                                Integer defCount = localToDefCount.get(m);
                                if (defCount == null || defCount == 0)
                                    throw new RuntimeException("Variable " + m + " used without definition!");
                                if (defCount == 1) {
                                    useBox.setValue(m);
                                    fastCopyPropagationCount++;
                                    continue;
                                }
                                List<Unit> path = graph.getExtendedBasicBlockPathBetween(def, stmt);
                                if (path == null) {
                                    // no path in the extended basic block
                                    continue;
                                }
                                Iterator<Unit> pathIt = path.iterator();
                                // Skip first node
                                pathIt.next();
                                // Make sure that m is not redefined along
                                // path
                                {
                                    boolean isRedefined = false;
                                    while (pathIt.hasNext()) {
                                        Stmt s = (Stmt) pathIt.next();
                                        if (stmt == s) {
                                            break;
                                        }
                                        if (s instanceof DefinitionStmt) {
                                            if (((DefinitionStmt) s).getLeftOp() == m) {
                                                isRedefined = true;
                                                break;
                                            }
                                        }
                                    }
                                    if (isRedefined)
                                        continue;
                                }
                                useBox.setValue(m);
                                slowCopyPropagationCount++;
                            }
                        }
                    }
                }
            }
        }
    }
    if (Options.v().verbose())
        logger.debug("[" + stmtBody.getMethod().getName() + "]     Propagated: " + fastCopyPropagationCount + " fast copies  " + slowCopyPropagationCount + " slow copies");
    if (Options.v().time())
        Timers.v().propagatorTimer.end();
}
Also used : HashMap(java.util.HashMap) NullConstant(soot.jimple.NullConstant) Constant(soot.jimple.Constant) LongConstant(soot.jimple.LongConstant) IntConstant(soot.jimple.IntConstant) AssignStmt(soot.jimple.AssignStmt) Unit(soot.Unit) Stmt(soot.jimple.Stmt) AssignStmt(soot.jimple.AssignStmt) DefinitionStmt(soot.jimple.DefinitionStmt) RefLikeType(soot.RefLikeType) ExceptionalUnitGraph(soot.toolkits.graph.ExceptionalUnitGraph) Iterator(java.util.Iterator) CastExpr(soot.jimple.CastExpr) IntConstant(soot.jimple.IntConstant) List(java.util.List) LongConstant(soot.jimple.LongConstant) PseudoTopologicalOrderer(soot.toolkits.graph.PseudoTopologicalOrderer) Local(soot.Local) LocalDefs(soot.toolkits.scalar.LocalDefs) ExceptionalUnitGraph(soot.toolkits.graph.ExceptionalUnitGraph) UnitGraph(soot.toolkits.graph.UnitGraph) ValueBox(soot.ValueBox) CPOptions(soot.options.CPOptions) NullType(soot.NullType) StmtBody(soot.jimple.StmtBody) DefinitionStmt(soot.jimple.DefinitionStmt)

Example 9 with NullType

use of soot.NullType in project soot by Sable.

the class LocalNameStandardizer method internalTransform.

@Override
protected void internalTransform(Body body, String phaseName, Map<String, String> options) {
    boolean onlyStackName = PhaseOptions.getBoolean(options, "only-stack-locals");
    boolean sortLocals = PhaseOptions.getBoolean(options, "sort-locals");
    final BooleanType booleanType = BooleanType.v();
    final ByteType byteType = ByteType.v();
    final ShortType shortType = ShortType.v();
    final CharType charType = CharType.v();
    final IntType intType = IntType.v();
    final LongType longType = LongType.v();
    final DoubleType doubleType = DoubleType.v();
    final FloatType floatType = FloatType.v();
    final ErroneousType erroneousType = ErroneousType.v();
    final UnknownType unknownType = UnknownType.v();
    final StmtAddressType stmtAddressType = StmtAddressType.v();
    final NullType nullType = NullType.v();
    // Change the names to the standard forms now.
    {
        int objectCount = 0;
        int intCount = 0;
        int longCount = 0;
        int floatCount = 0;
        int doubleCount = 0;
        int addressCount = 0;
        int errorCount = 0;
        int nullCount = 0;
        /* The goal of this option is to ensure that local ordering remains
             * consistent between different iterations of soot. This helps to ensure
             * things like stable string representations of instructions and stable
             * jimple representations of a methods body when soot is used to load
             * the same code in different iterations.
             * 
             * First sorts the locals alphabetically by the string representation of
             * their type. Then if there are two locals with the same type, it uses
             * the only other source of structurally stable information (i.e. the 
             * instructions themselves) to produce an ordering for the locals
             * that remains consistent between different soot instances. It achieves
             * this by determining the position of a local's first occurrence in the 
             * instruction's list of definition statements. This position is then used
             * to sort the locals with the same type in an ascending order. 
             * 
             * The only times that this may not produce a consistent ordering for the 
             * locals between different soot instances is if a local is never defined in
             * the instructions or if the instructions themselves are changed in some way
             * that effects the ordering of the locals. In the first case, if a local is 
             * never defined, the other jimple body phases will remove this local as it is 
             * unused. As such, all we have to do is rerun this LocalNameStandardizer after
             * all other jimple body phases to eliminate any ambiguity introduced by these
             * phases and by the removed unused locals. In the second case, if the instructions
             * themselves changed then the user would have had to intentionally told soot to
             * modify the instructions of the code. Otherwise, the instructions would not have
             * changed because we assume the instructions to always be structurally stable
             * between different instances of soot. As such, in this instance, the user should
             * not be expecting soot to produce the same output as the input and thus the
             * ordering of the locals does not matter.
             */
        if (sortLocals) {
            Chain<Local> locals = body.getLocals();
            final List<ValueBox> defs = body.getDefBoxes();
            ArrayList<Local> sortedLocals = new ArrayList<Local>(locals);
            Collections.sort(sortedLocals, new Comparator<Local>() {

                private Map<Local, Integer> firstOccuranceCache = new HashMap<Local, Integer>();

                @Override
                public int compare(Local arg0, Local arg1) {
                    int ret = arg0.getType().toString().compareTo(arg1.getType().toString());
                    if (ret == 0) {
                        ret = Integer.compare(getFirstOccurance(arg0), getFirstOccurance(arg1));
                    }
                    return ret;
                }

                private int getFirstOccurance(Local l) {
                    Integer cur = firstOccuranceCache.get(l);
                    if (cur != null) {
                        return cur;
                    } else {
                        int count = 0;
                        int first = -1;
                        for (ValueBox vb : defs) {
                            Value v = vb.getValue();
                            if (v instanceof Local && v.equals(l)) {
                                first = count;
                                break;
                            }
                            count++;
                        }
                        firstOccuranceCache.put(l, first);
                        return first;
                    }
                }
            });
            locals.clear();
            locals.addAll(sortedLocals);
        }
        for (Local l : body.getLocals()) {
            String prefix = "";
            if (l.getName().startsWith("$"))
                prefix = "$";
            else {
                if (onlyStackName)
                    continue;
            }
            final Type type = l.getType();
            if (type.equals(booleanType))
                l.setName(prefix + "z" + intCount++);
            else if (type.equals(byteType))
                l.setName(prefix + "b" + longCount++);
            else if (type.equals(shortType))
                l.setName(prefix + "s" + longCount++);
            else if (type.equals(charType))
                l.setName(prefix + "c" + longCount++);
            else if (type.equals(intType))
                l.setName(prefix + "i" + longCount++);
            else if (type.equals(longType))
                l.setName(prefix + "l" + longCount++);
            else if (type.equals(doubleType))
                l.setName(prefix + "d" + doubleCount++);
            else if (type.equals(floatType))
                l.setName(prefix + "f" + floatCount++);
            else if (type.equals(stmtAddressType))
                l.setName(prefix + "a" + addressCount++);
            else if (type.equals(erroneousType) || type.equals(unknownType)) {
                l.setName(prefix + "e" + errorCount++);
            } else if (type.equals(nullType))
                l.setName(prefix + "n" + nullCount++);
            else
                l.setName(prefix + "r" + objectCount++);
        }
    }
}
Also used : Chain(soot.util.Chain) LongType(soot.LongType) ArrayList(java.util.ArrayList) ByteType(soot.ByteType) IntType(soot.IntType) FloatType(soot.FloatType) Comparator(java.util.Comparator) ErroneousType(soot.ErroneousType) ArrayList(java.util.ArrayList) List(java.util.List) ShortType(soot.ShortType) BooleanType(soot.BooleanType) Local(soot.Local) UnknownType(soot.UnknownType) UnknownType(soot.UnknownType) DoubleType(soot.DoubleType) FloatType(soot.FloatType) IntType(soot.IntType) ShortType(soot.ShortType) CharType(soot.CharType) LongType(soot.LongType) NullType(soot.NullType) StmtAddressType(soot.StmtAddressType) BooleanType(soot.BooleanType) ErroneousType(soot.ErroneousType) ByteType(soot.ByteType) Type(soot.Type) DoubleType(soot.DoubleType) ValueBox(soot.ValueBox) Value(soot.Value) CharType(soot.CharType) StmtAddressType(soot.StmtAddressType) NullType(soot.NullType) HashMap(java.util.HashMap) Map(java.util.Map)

Example 10 with NullType

use of soot.NullType in project soot by Sable.

the class UseChecker method caseAssignStmt.

public void caseAssignStmt(AssignStmt stmt) {
    Value lhs = stmt.getLeftOp();
    Value rhs = stmt.getRightOp();
    Type tlhs = null;
    if (lhs instanceof Local)
        tlhs = this.tg.get((Local) lhs);
    else if (lhs instanceof ArrayRef) {
        ArrayRef aref = (ArrayRef) lhs;
        Local base = (Local) aref.getBase();
        // Try to force Type integrity. The left side must agree on the
        // element type of the right side array reference.
        ArrayType at = null;
        Type tgType = this.tg.get(base);
        if (tgType instanceof ArrayType)
            at = (ArrayType) tgType;
        else {
            // is java.lang.Object
            if (tgType == Scene.v().getObjectType() && rhs instanceof Local) {
                Type rhsType = this.tg.get((Local) rhs);
                if (rhsType instanceof PrimType) {
                    if (defs == null) {
                        defs = LocalDefs.Factory.newLocalDefs(jb);
                        uses = LocalUses.Factory.newLocalUses(jb, defs);
                    }
                    // Check the original type of the array from the alloc site
                    for (Unit defU : defs.getDefsOfAt(base, stmt)) {
                        if (defU instanceof AssignStmt) {
                            AssignStmt defUas = (AssignStmt) defU;
                            if (defUas.getRightOp() instanceof NewArrayExpr) {
                                at = (ArrayType) defUas.getRightOp().getType();
                                break;
                            }
                        }
                    }
                }
            }
            if (at == null)
                at = tgType.makeArrayType();
        }
        tlhs = ((ArrayType) at).getElementType();
        this.handleArrayRef(aref, stmt);
        aref.setBase((Local) this.uv.visit(aref.getBase(), at, stmt));
        stmt.setRightOp(this.uv.visit(rhs, tlhs, stmt));
        stmt.setLeftOp(this.uv.visit(lhs, tlhs, stmt));
    } else if (lhs instanceof FieldRef) {
        tlhs = ((FieldRef) lhs).getFieldRef().type();
        if (lhs instanceof InstanceFieldRef)
            this.handleInstanceFieldRef((InstanceFieldRef) lhs, stmt);
    }
    // They may have been changed above
    lhs = stmt.getLeftOp();
    rhs = stmt.getRightOp();
    if (rhs instanceof Local)
        stmt.setRightOp(this.uv.visit(rhs, tlhs, stmt));
    else if (rhs instanceof ArrayRef) {
        ArrayRef aref = (ArrayRef) rhs;
        Local base = (Local) aref.getBase();
        // try to force Type integrity
        ArrayType at = null;
        Type et = null;
        if (this.tg.get(base) instanceof ArrayType)
            at = (ArrayType) this.tg.get(base);
        else {
            Type bt = this.tg.get(base);
            // For some fixed type T, we assume that we can fix the array to T[].
            if (bt instanceof RefType || bt instanceof NullType) {
                RefType rt = bt instanceof NullType ? null : (RefType) bt;
                if (rt == null || rt.getSootClass().getName().equals("java.lang.Object") || rt.getSootClass().getName().equals("java.io.Serializable") || rt.getSootClass().getName().equals("java.lang.Cloneable")) {
                    if (defs == null) {
                        defs = LocalDefs.Factory.newLocalDefs(jb);
                        uses = LocalUses.Factory.newLocalUses(jb, defs);
                    }
                    outer: for (UnitValueBoxPair usePair : uses.getUsesOf(stmt)) {
                        Stmt useStmt = (Stmt) usePair.getUnit();
                        // from the callee's signature=
                        if (useStmt.containsInvokeExpr()) {
                            for (int i = 0; i < useStmt.getInvokeExpr().getArgCount(); i++) {
                                if (useStmt.getInvokeExpr().getArg(i) == usePair.getValueBox().getValue()) {
                                    et = useStmt.getInvokeExpr().getMethod().getParameterType(i);
                                    at = et.makeArrayType();
                                    break outer;
                                }
                            }
                        } else // if the other value is a primitive.
                        if (useStmt instanceof IfStmt) {
                            IfStmt ifStmt = (IfStmt) useStmt;
                            if (ifStmt.getCondition() instanceof EqExpr) {
                                EqExpr expr = (EqExpr) ifStmt.getCondition();
                                final Value other;
                                if (expr.getOp1() == usePair.getValueBox().getValue())
                                    other = expr.getOp2();
                                else
                                    other = expr.getOp1();
                                Type newEt = getTargetType(other);
                                if (newEt != null)
                                    et = newEt;
                            }
                        } else if (useStmt instanceof AssignStmt) {
                            // For binary expressions, we can look for type information in the
                            // other operands
                            AssignStmt useAssignStmt = (AssignStmt) useStmt;
                            if (useAssignStmt.getRightOp() instanceof BinopExpr) {
                                BinopExpr binOp = (BinopExpr) useAssignStmt.getRightOp();
                                final Value other;
                                if (binOp.getOp1() == usePair.getValueBox().getValue())
                                    other = binOp.getOp2();
                                else
                                    other = binOp.getOp1();
                                Type newEt = getTargetType(other);
                                if (newEt != null)
                                    et = newEt;
                            }
                        } else if (useStmt instanceof ReturnStmt) {
                            et = jb.getMethod().getReturnType();
                        }
                    }
                }
            }
            if (at == null)
                at = et.makeArrayType();
        }
        Type trhs = ((ArrayType) at).getElementType();
        this.handleArrayRef(aref, stmt);
        aref.setBase((Local) this.uv.visit(aref.getBase(), at, stmt));
        stmt.setRightOp(this.uv.visit(rhs, trhs, stmt));
    } else if (rhs instanceof InstanceFieldRef) {
        this.handleInstanceFieldRef((InstanceFieldRef) rhs, stmt);
        stmt.setRightOp(this.uv.visit(rhs, tlhs, stmt));
    } else if (rhs instanceof BinopExpr)
        this.handleBinopExpr((BinopExpr) rhs, stmt, tlhs);
    else if (rhs instanceof InvokeExpr) {
        this.handleInvokeExpr((InvokeExpr) rhs, stmt);
        stmt.setRightOp(this.uv.visit(rhs, tlhs, stmt));
    } else if (rhs instanceof CastExpr)
        stmt.setRightOp(this.uv.visit(rhs, tlhs, stmt));
    else if (rhs instanceof InstanceOfExpr) {
        InstanceOfExpr ioe = (InstanceOfExpr) rhs;
        ioe.setOp(this.uv.visit(ioe.getOp(), RefType.v("java.lang.Object"), stmt));
        stmt.setRightOp(this.uv.visit(rhs, tlhs, stmt));
    } else if (rhs instanceof NewArrayExpr) {
        NewArrayExpr nae = (NewArrayExpr) rhs;
        nae.setSize(this.uv.visit(nae.getSize(), IntType.v(), stmt));
        stmt.setRightOp(this.uv.visit(rhs, tlhs, stmt));
    } else if (rhs instanceof NewMultiArrayExpr) {
        NewMultiArrayExpr nmae = (NewMultiArrayExpr) rhs;
        for (int i = 0; i < nmae.getSizeCount(); i++) nmae.setSize(i, this.uv.visit(nmae.getSize(i), IntType.v(), stmt));
        stmt.setRightOp(this.uv.visit(rhs, tlhs, stmt));
    } else if (rhs instanceof LengthExpr) {
        stmt.setRightOp(this.uv.visit(rhs, tlhs, stmt));
    } else if (rhs instanceof NegExpr) {
        ((NegExpr) rhs).setOp(this.uv.visit(((NegExpr) rhs).getOp(), tlhs, stmt));
    } else if (rhs instanceof Constant)
        if (!(rhs instanceof NullConstant))
            stmt.setRightOp(this.uv.visit(rhs, tlhs, stmt));
}
Also used : AssignStmt(soot.jimple.AssignStmt) NewMultiArrayExpr(soot.jimple.NewMultiArrayExpr) NullConstant(soot.jimple.NullConstant) Constant(soot.jimple.Constant) NegExpr(soot.jimple.NegExpr) Unit(soot.Unit) BreakpointStmt(soot.jimple.BreakpointStmt) ReturnVoidStmt(soot.jimple.ReturnVoidStmt) InvokeStmt(soot.jimple.InvokeStmt) EnterMonitorStmt(soot.jimple.EnterMonitorStmt) NopStmt(soot.jimple.NopStmt) GotoStmt(soot.jimple.GotoStmt) AssignStmt(soot.jimple.AssignStmt) ThrowStmt(soot.jimple.ThrowStmt) IfStmt(soot.jimple.IfStmt) IdentityStmt(soot.jimple.IdentityStmt) TableSwitchStmt(soot.jimple.TableSwitchStmt) LookupSwitchStmt(soot.jimple.LookupSwitchStmt) ReturnStmt(soot.jimple.ReturnStmt) ExitMonitorStmt(soot.jimple.ExitMonitorStmt) Stmt(soot.jimple.Stmt) ArrayRef(soot.jimple.ArrayRef) ArrayType(soot.ArrayType) RefType(soot.RefType) InstanceInvokeExpr(soot.jimple.InstanceInvokeExpr) InvokeExpr(soot.jimple.InvokeExpr) InstanceFieldRef(soot.jimple.InstanceFieldRef) CastExpr(soot.jimple.CastExpr) PrimType(soot.PrimType) UnitValueBoxPair(soot.toolkits.scalar.UnitValueBoxPair) FieldRef(soot.jimple.FieldRef) InstanceFieldRef(soot.jimple.InstanceFieldRef) LengthExpr(soot.jimple.LengthExpr) Local(soot.Local) NullConstant(soot.jimple.NullConstant) InstanceOfExpr(soot.jimple.InstanceOfExpr) RefType(soot.RefType) BooleanType(soot.BooleanType) Type(soot.Type) IntType(soot.IntType) NullType(soot.NullType) ArrayType(soot.ArrayType) IntegerType(soot.IntegerType) PrimType(soot.PrimType) IfStmt(soot.jimple.IfStmt) NewArrayExpr(soot.jimple.NewArrayExpr) EqExpr(soot.jimple.EqExpr) Value(soot.Value) NullType(soot.NullType) ReturnStmt(soot.jimple.ReturnStmt) BinopExpr(soot.jimple.BinopExpr)

Aggregations

NullType (soot.NullType)18 Type (soot.Type)15 Local (soot.Local)13 RefType (soot.RefType)12 IntType (soot.IntType)11 ArrayType (soot.ArrayType)10 Value (soot.Value)10 LongType (soot.LongType)9 DoubleType (soot.DoubleType)8 FloatType (soot.FloatType)8 CastExpr (soot.jimple.CastExpr)7 BooleanType (soot.BooleanType)6 PrimType (soot.PrimType)6 ValueBox (soot.ValueBox)6 ArrayRef (soot.jimple.ArrayRef)6 NullConstant (soot.jimple.NullConstant)6 ByteType (soot.ByteType)5 CharType (soot.CharType)5 ShortType (soot.ShortType)5 Unit (soot.Unit)5