Search in sources :

Example 6 with UnitValueBoxPair

use of soot.toolkits.scalar.UnitValueBoxPair 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

Local (soot.Local)6 Unit (soot.Unit)6 Value (soot.Value)6 AssignStmt (soot.jimple.AssignStmt)6 ArrayList (java.util.ArrayList)5 UnitValueBoxPair (soot.toolkits.scalar.UnitValueBoxPair)5 ArrayRef (soot.jimple.ArrayRef)4 InvokeExpr (soot.jimple.InvokeExpr)4 Stmt (soot.jimple.Stmt)4 HashSet (java.util.HashSet)3 IntType (soot.IntType)3 RefType (soot.RefType)3 Type (soot.Type)3 ValueBox (soot.ValueBox)3 BinopExpr (soot.jimple.BinopExpr)3 CastExpr (soot.jimple.CastExpr)3 FieldRef (soot.jimple.FieldRef)3 InvokeStmt (soot.jimple.InvokeStmt)3 NewArrayExpr (soot.jimple.NewArrayExpr)3 NopStmt (soot.jimple.NopStmt)3