Search in sources :

Example 1 with NullConstant

use of soot.jimple.NullConstant in project soot by Sable.

the class ConstraintCollector method caseAssignStmt.

public void caseAssignStmt(AssignStmt stmt) {
    Value l = stmt.getLeftOp();
    Value r = stmt.getRightOp();
    TypeVariable left = null;
    TypeVariable right = null;
    if (l instanceof ArrayRef) {
        ArrayRef ref = (ArrayRef) l;
        Value base = ref.getBase();
        Value index = ref.getIndex();
        TypeVariable baseType = resolver.typeVariable((Local) base);
        baseType.makeElement();
        left = baseType.element();
        if (index instanceof Local) {
            if (uses) {
                resolver.typeVariable((Local) index).addParent(resolver.typeVariable(IntType.v()));
            }
        }
    } else if (l instanceof Local) {
        left = resolver.typeVariable((Local) l);
    } else if (l instanceof InstanceFieldRef) {
        InstanceFieldRef ref = (InstanceFieldRef) l;
        if (uses) {
            TypeVariable baseType = resolver.typeVariable((Local) ref.getBase());
            baseType.addParent(resolver.typeVariable(ref.getField().getDeclaringClass()));
            left = resolver.typeVariable(ref.getField().getType());
        }
    } else if (l instanceof StaticFieldRef) {
        if (uses) {
            StaticFieldRef ref = (StaticFieldRef) l;
            left = resolver.typeVariable(ref.getField().getType());
        }
    } else {
        throw new RuntimeException("Unhandled assignment left hand side type: " + l.getClass());
    }
    if (r instanceof ArrayRef) {
        ArrayRef ref = (ArrayRef) r;
        Value base = ref.getBase();
        Value index = ref.getIndex();
        TypeVariable baseType = resolver.typeVariable((Local) base);
        baseType.makeElement();
        right = baseType.element();
        if (index instanceof Local) {
            if (uses) {
                resolver.typeVariable((Local) index).addParent(resolver.typeVariable(IntType.v()));
            }
        }
    } else if (r instanceof DoubleConstant) {
        right = resolver.typeVariable(DoubleType.v());
    } else if (r instanceof FloatConstant) {
        right = resolver.typeVariable(FloatType.v());
    } else if (r instanceof IntConstant) {
        right = resolver.typeVariable(IntType.v());
    } else if (r instanceof LongConstant) {
        right = resolver.typeVariable(LongType.v());
    } else if (r instanceof NullConstant) {
        right = resolver.typeVariable(NullType.v());
    } else if (r instanceof StringConstant) {
        right = resolver.typeVariable(RefType.v("java.lang.String"));
    } else if (r instanceof ClassConstant) {
        right = resolver.typeVariable(RefType.v("java.lang.Class"));
    } else if (r instanceof BinopExpr) {
        // ******** BINOP EXPR ********
        BinopExpr be = (BinopExpr) r;
        Value lv = be.getOp1();
        Value rv = be.getOp2();
        TypeVariable lop;
        TypeVariable rop;
        // ******** LEFT ********
        if (lv instanceof Local) {
            lop = resolver.typeVariable((Local) lv);
        } else if (lv instanceof DoubleConstant) {
            lop = resolver.typeVariable(DoubleType.v());
        } else if (lv instanceof FloatConstant) {
            lop = resolver.typeVariable(FloatType.v());
        } else if (lv instanceof IntConstant) {
            lop = resolver.typeVariable(IntType.v());
        } else if (lv instanceof LongConstant) {
            lop = resolver.typeVariable(LongType.v());
        } else if (lv instanceof NullConstant) {
            lop = resolver.typeVariable(NullType.v());
        } else if (lv instanceof StringConstant) {
            lop = resolver.typeVariable(RefType.v("java.lang.String"));
        } else if (lv instanceof ClassConstant) {
            lop = resolver.typeVariable(RefType.v("java.lang.Class"));
        } else {
            throw new RuntimeException("Unhandled binary expression left operand type: " + lv.getClass());
        }
        // ******** RIGHT ********
        if (rv instanceof Local) {
            rop = resolver.typeVariable((Local) rv);
        } else if (rv instanceof DoubleConstant) {
            rop = resolver.typeVariable(DoubleType.v());
        } else if (rv instanceof FloatConstant) {
            rop = resolver.typeVariable(FloatType.v());
        } else if (rv instanceof IntConstant) {
            rop = resolver.typeVariable(IntType.v());
        } else if (rv instanceof LongConstant) {
            rop = resolver.typeVariable(LongType.v());
        } else if (rv instanceof NullConstant) {
            rop = resolver.typeVariable(NullType.v());
        } else if (rv instanceof StringConstant) {
            rop = resolver.typeVariable(RefType.v("java.lang.String"));
        } else if (rv instanceof ClassConstant) {
            rop = resolver.typeVariable(RefType.v("java.lang.Class"));
        } else {
            throw new RuntimeException("Unhandled binary expression right operand type: " + rv.getClass());
        }
        if ((be instanceof AddExpr) || (be instanceof SubExpr) || (be instanceof MulExpr) || (be instanceof DivExpr) || (be instanceof RemExpr) || (be instanceof AndExpr) || (be instanceof OrExpr) || (be instanceof XorExpr)) {
            if (uses) {
                TypeVariable common = resolver.typeVariable();
                rop.addParent(common);
                lop.addParent(common);
            }
            if (left != null) {
                rop.addParent(left);
                lop.addParent(left);
            }
        } else if ((be instanceof ShlExpr) || (be instanceof ShrExpr) || (be instanceof UshrExpr)) {
            if (uses) {
                rop.addParent(resolver.typeVariable(IntType.v()));
            }
            right = lop;
        } else if ((be instanceof CmpExpr) || (be instanceof CmpgExpr) || (be instanceof CmplExpr) || (be instanceof EqExpr) || (be instanceof GeExpr) || (be instanceof GtExpr) || (be instanceof LeExpr) || (be instanceof LtExpr) || (be instanceof NeExpr)) {
            if (uses) {
                TypeVariable common = resolver.typeVariable();
                rop.addParent(common);
                lop.addParent(common);
            }
            right = resolver.typeVariable(IntType.v());
        } else {
            throw new RuntimeException("Unhandled binary expression type: " + be.getClass());
        }
    } else if (r instanceof CastExpr) {
        CastExpr ce = (CastExpr) r;
        right = resolver.typeVariable(ce.getCastType());
    } else if (r instanceof InstanceOfExpr) {
        right = resolver.typeVariable(IntType.v());
    } else if (r instanceof InvokeExpr) {
        InvokeExpr ie = (InvokeExpr) r;
        handleInvokeExpr(ie);
        right = resolver.typeVariable(ie.getMethodRef().returnType());
    } else if (r instanceof NewArrayExpr) {
        NewArrayExpr nae = (NewArrayExpr) r;
        Type baseType = nae.getBaseType();
        if (baseType instanceof ArrayType) {
            right = resolver.typeVariable(ArrayType.v(((ArrayType) baseType).baseType, ((ArrayType) baseType).numDimensions + 1));
        } else {
            right = resolver.typeVariable(ArrayType.v(baseType, 1));
        }
        if (uses) {
            Value size = nae.getSize();
            if (size instanceof Local) {
                TypeVariable var = resolver.typeVariable((Local) size);
                var.addParent(resolver.typeVariable(IntType.v()));
            }
        }
    } else if (r instanceof NewExpr) {
        NewExpr na = (NewExpr) r;
        right = resolver.typeVariable(na.getBaseType());
    } else if (r instanceof NewMultiArrayExpr) {
        NewMultiArrayExpr nmae = (NewMultiArrayExpr) r;
        right = resolver.typeVariable(nmae.getBaseType());
        if (uses) {
            for (int i = 0; i < nmae.getSizeCount(); i++) {
                Value size = nmae.getSize(i);
                if (size instanceof Local) {
                    TypeVariable var = resolver.typeVariable((Local) size);
                    var.addParent(resolver.typeVariable(IntType.v()));
                }
            }
        }
    } else if (r instanceof LengthExpr) {
        LengthExpr le = (LengthExpr) r;
        if (uses) {
            if (le.getOp() instanceof Local) {
                resolver.typeVariable((Local) le.getOp()).makeElement();
            }
        }
        right = resolver.typeVariable(IntType.v());
    } else if (r instanceof NegExpr) {
        NegExpr ne = (NegExpr) r;
        if (ne.getOp() instanceof Local) {
            right = resolver.typeVariable((Local) ne.getOp());
        } else if (ne.getOp() instanceof DoubleConstant) {
            right = resolver.typeVariable(DoubleType.v());
        } else if (ne.getOp() instanceof FloatConstant) {
            right = resolver.typeVariable(FloatType.v());
        } else if (ne.getOp() instanceof IntConstant) {
            right = resolver.typeVariable(IntType.v());
        } else if (ne.getOp() instanceof LongConstant) {
            right = resolver.typeVariable(LongType.v());
        } else {
            throw new RuntimeException("Unhandled neg expression operand type: " + ne.getOp().getClass());
        }
    } else if (r instanceof Local) {
        right = resolver.typeVariable((Local) r);
    } else if (r instanceof InstanceFieldRef) {
        InstanceFieldRef ref = (InstanceFieldRef) r;
        if (uses) {
            TypeVariable baseType = resolver.typeVariable((Local) ref.getBase());
            baseType.addParent(resolver.typeVariable(ref.getField().getDeclaringClass()));
        }
        right = resolver.typeVariable(ref.getField().getType());
    } else if (r instanceof StaticFieldRef) {
        StaticFieldRef ref = (StaticFieldRef) r;
        right = resolver.typeVariable(ref.getField().getType());
    } else {
        throw new RuntimeException("Unhandled assignment right hand side type: " + r.getClass());
    }
    if (left != null && right != null) {
        right.addParent(left);
    }
}
Also used : MulExpr(soot.jimple.MulExpr) AndExpr(soot.jimple.AndExpr) DoubleConstant(soot.jimple.DoubleConstant) NewMultiArrayExpr(soot.jimple.NewMultiArrayExpr) FloatConstant(soot.jimple.FloatConstant) GtExpr(soot.jimple.GtExpr) LtExpr(soot.jimple.LtExpr) NegExpr(soot.jimple.NegExpr) GeExpr(soot.jimple.GeExpr) UshrExpr(soot.jimple.UshrExpr) LeExpr(soot.jimple.LeExpr) ArrayRef(soot.jimple.ArrayRef) ArrayType(soot.ArrayType) InterfaceInvokeExpr(soot.jimple.InterfaceInvokeExpr) DynamicInvokeExpr(soot.jimple.DynamicInvokeExpr) VirtualInvokeExpr(soot.jimple.VirtualInvokeExpr) InvokeExpr(soot.jimple.InvokeExpr) SpecialInvokeExpr(soot.jimple.SpecialInvokeExpr) StaticInvokeExpr(soot.jimple.StaticInvokeExpr) InstanceFieldRef(soot.jimple.InstanceFieldRef) CastExpr(soot.jimple.CastExpr) IntConstant(soot.jimple.IntConstant) ShlExpr(soot.jimple.ShlExpr) LongConstant(soot.jimple.LongConstant) XorExpr(soot.jimple.XorExpr) NeExpr(soot.jimple.NeExpr) LengthExpr(soot.jimple.LengthExpr) SubExpr(soot.jimple.SubExpr) Local(soot.Local) NullConstant(soot.jimple.NullConstant) AddExpr(soot.jimple.AddExpr) InstanceOfExpr(soot.jimple.InstanceOfExpr) OrExpr(soot.jimple.OrExpr) StaticFieldRef(soot.jimple.StaticFieldRef) DivExpr(soot.jimple.DivExpr) RefType(soot.RefType) Type(soot.Type) DoubleType(soot.DoubleType) FloatType(soot.FloatType) IntType(soot.IntType) LongType(soot.LongType) NullType(soot.NullType) ArrayType(soot.ArrayType) NewArrayExpr(soot.jimple.NewArrayExpr) RemExpr(soot.jimple.RemExpr) ShrExpr(soot.jimple.ShrExpr) CmpExpr(soot.jimple.CmpExpr) EqExpr(soot.jimple.EqExpr) CmpgExpr(soot.jimple.CmpgExpr) Value(soot.Value) NewExpr(soot.jimple.NewExpr) StringConstant(soot.jimple.StringConstant) CmplExpr(soot.jimple.CmplExpr) ClassConstant(soot.jimple.ClassConstant) BinopExpr(soot.jimple.BinopExpr)

Example 2 with NullConstant

use of soot.jimple.NullConstant in project soot by Sable.

the class ConstraintCollector method caseIfStmt.

public void caseIfStmt(IfStmt stmt) {
    if (uses) {
        ConditionExpr cond = (ConditionExpr) stmt.getCondition();
        BinopExpr expr = cond;
        Value lv = expr.getOp1();
        Value rv = expr.getOp2();
        TypeVariable lop;
        TypeVariable rop;
        // ******** LEFT ********
        if (lv instanceof Local) {
            lop = resolver.typeVariable((Local) lv);
        } else if (lv instanceof DoubleConstant) {
            lop = resolver.typeVariable(DoubleType.v());
        } else if (lv instanceof FloatConstant) {
            lop = resolver.typeVariable(FloatType.v());
        } else if (lv instanceof IntConstant) {
            lop = resolver.typeVariable(IntType.v());
        } else if (lv instanceof LongConstant) {
            lop = resolver.typeVariable(LongType.v());
        } else if (lv instanceof NullConstant) {
            lop = resolver.typeVariable(NullType.v());
        } else if (lv instanceof StringConstant) {
            lop = resolver.typeVariable(RefType.v("java.lang.String"));
        } else if (lv instanceof ClassConstant) {
            lop = resolver.typeVariable(RefType.v("java.lang.Class"));
        } else {
            throw new RuntimeException("Unhandled binary expression left operand type: " + lv.getClass());
        }
        // ******** RIGHT ********
        if (rv instanceof Local) {
            rop = resolver.typeVariable((Local) rv);
        } else if (rv instanceof DoubleConstant) {
            rop = resolver.typeVariable(DoubleType.v());
        } else if (rv instanceof FloatConstant) {
            rop = resolver.typeVariable(FloatType.v());
        } else if (rv instanceof IntConstant) {
            rop = resolver.typeVariable(IntType.v());
        } else if (rv instanceof LongConstant) {
            rop = resolver.typeVariable(LongType.v());
        } else if (rv instanceof NullConstant) {
            rop = resolver.typeVariable(NullType.v());
        } else if (rv instanceof StringConstant) {
            rop = resolver.typeVariable(RefType.v("java.lang.String"));
        } else if (rv instanceof ClassConstant) {
            rop = resolver.typeVariable(RefType.v("java.lang.Class"));
        } else {
            throw new RuntimeException("Unhandled binary expression right operand type: " + rv.getClass());
        }
        TypeVariable common = resolver.typeVariable();
        rop.addParent(common);
        lop.addParent(common);
    }
}
Also used : LongConstant(soot.jimple.LongConstant) DoubleConstant(soot.jimple.DoubleConstant) FloatConstant(soot.jimple.FloatConstant) Local(soot.Local) NullConstant(soot.jimple.NullConstant) ConditionExpr(soot.jimple.ConditionExpr) Value(soot.Value) IntConstant(soot.jimple.IntConstant) StringConstant(soot.jimple.StringConstant) ClassConstant(soot.jimple.ClassConstant) BinopExpr(soot.jimple.BinopExpr)

Example 3 with NullConstant

use of soot.jimple.NullConstant in project soot by Sable.

the class ConstraintCollector method caseAssignStmt.

public void caseAssignStmt(AssignStmt stmt) {
    Value l = stmt.getLeftOp();
    Value r = stmt.getRightOp();
    TypeVariable left = null;
    TypeVariable right = null;
    if (l instanceof ArrayRef) {
        ArrayRef ref = (ArrayRef) l;
        Type baset = ((Local) ref.getBase()).getType();
        if (baset instanceof ArrayType) {
            ArrayType base = (ArrayType) baset;
            Value index = ref.getIndex();
            if (uses) {
                if ((base.numDimensions == 1) && (base.baseType instanceof IntegerType)) {
                    left = resolver.typeVariable(base.baseType);
                }
                if (index instanceof Local) {
                    resolver.typeVariable((Local) index).addParent(resolver.INT);
                }
            }
        }
    } else if (l instanceof Local) {
        if (((Local) l).getType() instanceof IntegerType) {
            left = resolver.typeVariable((Local) l);
        }
    } else if (l instanceof InstanceFieldRef) {
        if (uses) {
            InstanceFieldRef ref = (InstanceFieldRef) l;
            Type fieldType = ref.getFieldRef().type();
            if (fieldType instanceof IntegerType) {
                left = resolver.typeVariable(ref.getFieldRef().type());
            }
        }
    } else if (l instanceof StaticFieldRef) {
        if (uses) {
            StaticFieldRef ref = (StaticFieldRef) l;
            Type fieldType = ref.getFieldRef().type();
            if (fieldType instanceof IntegerType) {
                left = resolver.typeVariable(ref.getFieldRef().type());
            }
        }
    } else {
        throw new RuntimeException("Unhandled assignment left hand side type: " + l.getClass());
    }
    if (r instanceof ArrayRef) {
        ArrayRef ref = (ArrayRef) r;
        Type baset = ((Local) ref.getBase()).getType();
        if (!(baset instanceof NullType)) {
            Value index = ref.getIndex();
            // Be careful, dex can do some weird object/array casting
            if (baset instanceof ArrayType) {
                ArrayType base = (ArrayType) baset;
                if ((base.numDimensions == 1) && (base.baseType instanceof IntegerType)) {
                    right = resolver.typeVariable(base.baseType);
                }
            } else if (baset instanceof IntegerType)
                right = resolver.typeVariable(baset);
            if (uses)
                if (index instanceof Local)
                    resolver.typeVariable((Local) index).addParent(resolver.INT);
        }
    } else if (r instanceof DoubleConstant) {
    } else if (r instanceof FloatConstant) {
    } else if (r instanceof IntConstant) {
        int value = ((IntConstant) r).value;
        if (value < -32768) {
            right = resolver.INT;
        } else if (value < -128) {
            right = resolver.SHORT;
        } else if (value < 0) {
            right = resolver.BYTE;
        } else if (value < 2) {
            right = resolver.R0_1;
        } else if (value < 128) {
            right = resolver.R0_127;
        } else if (value < 32768) {
            right = resolver.R0_32767;
        } else if (value < 65536) {
            right = resolver.CHAR;
        } else {
            right = resolver.INT;
        }
    } else if (r instanceof LongConstant) {
    } else if (r instanceof NullConstant) {
    } else if (r instanceof StringConstant) {
    } else if (r instanceof ClassConstant) {
    } else if (r instanceof BinopExpr) {
        // ******** BINOP EXPR ********
        BinopExpr be = (BinopExpr) r;
        Value lv = be.getOp1();
        Value rv = be.getOp2();
        TypeVariable lop = null;
        TypeVariable rop = null;
        // ******** LEFT ********
        if (lv instanceof Local) {
            if (((Local) lv).getType() instanceof IntegerType) {
                lop = resolver.typeVariable((Local) lv);
            }
        } else if (lv instanceof DoubleConstant) {
        } else if (lv instanceof FloatConstant) {
        } else if (lv instanceof IntConstant) {
            int value = ((IntConstant) lv).value;
            if (value < -32768) {
                lop = resolver.INT;
            } else if (value < -128) {
                lop = resolver.SHORT;
            } else if (value < 0) {
                lop = resolver.BYTE;
            } else if (value < 2) {
                lop = resolver.R0_1;
            } else if (value < 128) {
                lop = resolver.R0_127;
            } else if (value < 32768) {
                lop = resolver.R0_32767;
            } else if (value < 65536) {
                lop = resolver.CHAR;
            } else {
                lop = resolver.INT;
            }
        } else if (lv instanceof LongConstant) {
        } else if (lv instanceof NullConstant) {
        } else if (lv instanceof StringConstant) {
        } else if (lv instanceof ClassConstant) {
        } else {
            throw new RuntimeException("Unhandled binary expression left operand type: " + lv.getClass());
        }
        // ******** RIGHT ********
        if (rv instanceof Local) {
            if (((Local) rv).getType() instanceof IntegerType) {
                rop = resolver.typeVariable((Local) rv);
            }
        } else if (rv instanceof DoubleConstant) {
        } else if (rv instanceof FloatConstant) {
        } else if (rv instanceof IntConstant) {
            int value = ((IntConstant) rv).value;
            if (value < -32768) {
                rop = resolver.INT;
            } else if (value < -128) {
                rop = resolver.SHORT;
            } else if (value < 0) {
                rop = resolver.BYTE;
            } else if (value < 2) {
                rop = resolver.R0_1;
            } else if (value < 128) {
                rop = resolver.R0_127;
            } else if (value < 32768) {
                rop = resolver.R0_32767;
            } else if (value < 65536) {
                rop = resolver.CHAR;
            } else {
                rop = resolver.INT;
            }
        } else if (rv instanceof LongConstant) {
        } else if (rv instanceof NullConstant) {
        } else if (rv instanceof StringConstant) {
        } else if (rv instanceof ClassConstant) {
        } else {
            throw new RuntimeException("Unhandled binary expression right operand type: " + rv.getClass());
        }
        if ((be instanceof AddExpr) || (be instanceof SubExpr) || (be instanceof DivExpr) || (be instanceof RemExpr) || (be instanceof MulExpr)) {
            if (lop != null && rop != null) {
                if (uses) {
                    if (lop.type() == null) {
                        lop.addParent(resolver.INT);
                    }
                    if (rop.type() == null) {
                        rop.addParent(resolver.INT);
                    }
                }
                right = resolver.INT;
            }
        } else if ((be instanceof AndExpr) || (be instanceof OrExpr) || (be instanceof XorExpr)) {
            if (lop != null && rop != null) {
                TypeVariable common = resolver.typeVariable();
                if (rop != null)
                    rop.addParent(common);
                if (lop != null)
                    lop.addParent(common);
                right = common;
            }
        } else if (be instanceof ShlExpr) {
            if (uses) {
                if (lop != null && lop.type() == null) {
                    lop.addParent(resolver.INT);
                }
                if (rop.type() == null) {
                    rop.addParent(resolver.INT);
                }
            }
            right = (lop == null) ? null : resolver.INT;
        } else if ((be instanceof ShrExpr) || (be instanceof UshrExpr)) {
            if (uses) {
                if (lop != null && lop.type() == null) {
                    lop.addParent(resolver.INT);
                }
                if (rop.type() == null) {
                    rop.addParent(resolver.INT);
                }
            }
            right = lop;
        } else if ((be instanceof CmpExpr) || (be instanceof CmpgExpr) || (be instanceof CmplExpr)) {
            right = resolver.BYTE;
        } else if ((be instanceof EqExpr) || (be instanceof GeExpr) || (be instanceof GtExpr) || (be instanceof LeExpr) || (be instanceof LtExpr) || (be instanceof NeExpr)) {
            if (uses) {
                TypeVariable common = resolver.typeVariable();
                if (rop != null)
                    rop.addParent(common);
                if (lop != null)
                    lop.addParent(common);
            }
            right = resolver.BOOLEAN;
        } else {
            throw new RuntimeException("Unhandled binary expression type: " + be.getClass());
        }
    } else if (r instanceof CastExpr) {
        CastExpr ce = (CastExpr) r;
        if (ce.getCastType() instanceof IntegerType) {
            right = resolver.typeVariable(ce.getCastType());
        }
    } else if (r instanceof InstanceOfExpr) {
        right = resolver.BOOLEAN;
    } else if (r instanceof InvokeExpr) {
        InvokeExpr ie = (InvokeExpr) r;
        handleInvokeExpr(ie);
        if (ie.getMethodRef().returnType() instanceof IntegerType) {
            right = resolver.typeVariable(ie.getMethodRef().returnType());
        }
    } else if (r instanceof NewArrayExpr) {
        NewArrayExpr nae = (NewArrayExpr) r;
        if (uses) {
            Value size = nae.getSize();
            if (size instanceof Local) {
                TypeVariable var = resolver.typeVariable((Local) size);
                var.addParent(resolver.INT);
            }
        }
    } else if (r instanceof NewExpr) {
    } else if (r instanceof NewMultiArrayExpr) {
        NewMultiArrayExpr nmae = (NewMultiArrayExpr) r;
        if (uses) {
            for (int i = 0; i < nmae.getSizeCount(); i++) {
                Value size = nmae.getSize(i);
                if (size instanceof Local) {
                    TypeVariable var = resolver.typeVariable((Local) size);
                    var.addParent(resolver.INT);
                }
            }
        }
    } else if (r instanceof LengthExpr) {
        right = resolver.INT;
    } else if (r instanceof NegExpr) {
        NegExpr ne = (NegExpr) r;
        if (ne.getOp() instanceof Local) {
            Local local = (Local) ne.getOp();
            if (local.getType() instanceof IntegerType) {
                if (uses) {
                    resolver.typeVariable(local).addParent(resolver.INT);
                }
                TypeVariable v = resolver.typeVariable();
                v.addChild(resolver.BYTE);
                v.addChild(resolver.typeVariable(local));
                right = v;
            }
        } else if (ne.getOp() instanceof DoubleConstant) {
        } else if (ne.getOp() instanceof FloatConstant) {
        } else if (ne.getOp() instanceof IntConstant) {
            int value = ((IntConstant) ne.getOp()).value;
            if (value < -32768) {
                right = resolver.INT;
            } else if (value < -128) {
                right = resolver.SHORT;
            } else if (value < 0) {
                right = resolver.BYTE;
            } else if (value < 2) {
                right = resolver.BYTE;
            } else if (value < 128) {
                right = resolver.BYTE;
            } else if (value < 32768) {
                right = resolver.SHORT;
            } else if (value < 65536) {
                right = resolver.INT;
            } else {
                right = resolver.INT;
            }
        } else if (ne.getOp() instanceof LongConstant) {
        } else {
            throw new RuntimeException("Unhandled neg expression operand type: " + ne.getOp().getClass());
        }
    } else if (r instanceof Local) {
        Local local = (Local) r;
        if (local.getType() instanceof IntegerType) {
            right = resolver.typeVariable(local);
        }
    } else if (r instanceof InstanceFieldRef) {
        InstanceFieldRef ref = (InstanceFieldRef) r;
        if (ref.getFieldRef().type() instanceof IntegerType) {
            right = resolver.typeVariable(ref.getFieldRef().type());
        }
    } else if (r instanceof StaticFieldRef) {
        StaticFieldRef ref = (StaticFieldRef) r;
        if (ref.getFieldRef().type() instanceof IntegerType) {
            right = resolver.typeVariable(ref.getFieldRef().type());
        }
    } else {
        throw new RuntimeException("Unhandled assignment right hand side type: " + r.getClass());
    }
    if (left != null && right != null && (left.type() == null || right.type() == null)) {
        right.addParent(left);
    }
}
Also used : MulExpr(soot.jimple.MulExpr) AndExpr(soot.jimple.AndExpr) DoubleConstant(soot.jimple.DoubleConstant) NewMultiArrayExpr(soot.jimple.NewMultiArrayExpr) FloatConstant(soot.jimple.FloatConstant) GtExpr(soot.jimple.GtExpr) LtExpr(soot.jimple.LtExpr) NegExpr(soot.jimple.NegExpr) GeExpr(soot.jimple.GeExpr) UshrExpr(soot.jimple.UshrExpr) LeExpr(soot.jimple.LeExpr) ArrayRef(soot.jimple.ArrayRef) ArrayType(soot.ArrayType) DynamicInvokeExpr(soot.jimple.DynamicInvokeExpr) InvokeExpr(soot.jimple.InvokeExpr) InstanceFieldRef(soot.jimple.InstanceFieldRef) CastExpr(soot.jimple.CastExpr) IntConstant(soot.jimple.IntConstant) ShlExpr(soot.jimple.ShlExpr) LongConstant(soot.jimple.LongConstant) XorExpr(soot.jimple.XorExpr) NeExpr(soot.jimple.NeExpr) LengthExpr(soot.jimple.LengthExpr) SubExpr(soot.jimple.SubExpr) Local(soot.Local) NullConstant(soot.jimple.NullConstant) AddExpr(soot.jimple.AddExpr) InstanceOfExpr(soot.jimple.InstanceOfExpr) OrExpr(soot.jimple.OrExpr) StaticFieldRef(soot.jimple.StaticFieldRef) IntegerType(soot.IntegerType) Type(soot.Type) NullType(soot.NullType) ArrayType(soot.ArrayType) IntegerType(soot.IntegerType) DivExpr(soot.jimple.DivExpr) NewArrayExpr(soot.jimple.NewArrayExpr) RemExpr(soot.jimple.RemExpr) ShrExpr(soot.jimple.ShrExpr) CmpExpr(soot.jimple.CmpExpr) EqExpr(soot.jimple.EqExpr) CmpgExpr(soot.jimple.CmpgExpr) Value(soot.Value) NewExpr(soot.jimple.NewExpr) NullType(soot.NullType) StringConstant(soot.jimple.StringConstant) CmplExpr(soot.jimple.CmplExpr) ClassConstant(soot.jimple.ClassConstant) BinopExpr(soot.jimple.BinopExpr)

Example 4 with NullConstant

use of soot.jimple.NullConstant 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 5 with NullConstant

use of soot.jimple.NullConstant in project soot by Sable.

the class NullCheckEliminator method internalTransform.

public void internalTransform(Body body, String phaseName, Map<String, String> options) {
    // really, the analysis should be able to use its own results to determine
    // that some branches are dead, but since it doesn't we just iterate.
    boolean changed;
    do {
        changed = false;
        NullnessAnalysis analysis = analysisFactory.newAnalysis(new ExceptionalUnitGraph(body));
        Chain<Unit> units = body.getUnits();
        Stmt s;
        for (s = (Stmt) units.getFirst(); s != null; s = (Stmt) units.getSuccOf(s)) {
            if (!(s instanceof IfStmt))
                continue;
            IfStmt is = (IfStmt) s;
            Value c = is.getCondition();
            if (!(c instanceof EqExpr || c instanceof NeExpr))
                continue;
            BinopExpr e = (BinopExpr) c;
            Immediate i = null;
            if (e.getOp1() instanceof NullConstant)
                i = (Immediate) e.getOp2();
            if (e.getOp2() instanceof NullConstant)
                i = (Immediate) e.getOp1();
            if (i == null)
                continue;
            boolean alwaysNull = analysis.isAlwaysNullBefore(s, i);
            boolean alwaysNonNull = analysis.isAlwaysNonNullBefore(s, i);
            // -1 => condition is false, 1 => condition is true
            int elim = 0;
            if (alwaysNonNull)
                elim = c instanceof EqExpr ? -1 : 1;
            if (alwaysNull)
                elim = c instanceof EqExpr ? 1 : -1;
            Stmt newstmt = null;
            if (elim == -1)
                newstmt = Jimple.v().newNopStmt();
            if (elim == 1)
                newstmt = Jimple.v().newGotoStmt(is.getTarget());
            if (newstmt != null) {
                units.swapWith(s, newstmt);
                s = newstmt;
                changed = true;
            }
        }
    } while (changed);
}
Also used : NeExpr(soot.jimple.NeExpr) Immediate(soot.Immediate) NullConstant(soot.jimple.NullConstant) Unit(soot.Unit) Stmt(soot.jimple.Stmt) IfStmt(soot.jimple.IfStmt) ExceptionalUnitGraph(soot.toolkits.graph.ExceptionalUnitGraph) IfStmt(soot.jimple.IfStmt) EqExpr(soot.jimple.EqExpr) Value(soot.Value) BinopExpr(soot.jimple.BinopExpr)

Aggregations

NullConstant (soot.jimple.NullConstant)17 Value (soot.Value)15 Local (soot.Local)13 IntConstant (soot.jimple.IntConstant)13 LongConstant (soot.jimple.LongConstant)11 BinopExpr (soot.jimple.BinopExpr)10 StringConstant (soot.jimple.StringConstant)10 Type (soot.Type)9 DoubleConstant (soot.jimple.DoubleConstant)9 FloatConstant (soot.jimple.FloatConstant)9 NullType (soot.NullType)8 ClassConstant (soot.jimple.ClassConstant)8 ArrayType (soot.ArrayType)7 ArrayRef (soot.jimple.ArrayRef)7 CastExpr (soot.jimple.CastExpr)7 InvokeExpr (soot.jimple.InvokeExpr)7 NewArrayExpr (soot.jimple.NewArrayExpr)7 Unit (soot.Unit)6 EqExpr (soot.jimple.EqExpr)6 InstanceFieldRef (soot.jimple.InstanceFieldRef)6