Search in sources :

Example 21 with ArrayType

use of soot.ArrayType in project robovm by robovm.

the class MarshalerLookup method findMarshalers.

public Marshaler findMarshalers(MarshalSite marshalSite) {
    soot.Type type = marshalSite.getType();
    SootClass sc = null;
    if (type instanceof RefType) {
        sc = ((RefType) type).getSootClass();
    } else if (type instanceof ArrayType && ((ArrayType) type).baseType instanceof RefType) {
        sc = ((RefType) ((ArrayType) type).baseType).getSootClass();
    }
    List<Marshaler> result = new ArrayList<>();
    Set<String> visited = new HashSet<>();
    Set<String> seen = new HashSet<>();
    if (sc != null) {
        findMarshalers(sc, result, visited, seen, false);
    }
    findMarshalers(marshalSite.method.getDeclaringClass(), result, visited, seen, searchBuiltins);
    for (Marshaler marshaler : result) {
        if (marshaler.canMarshal(marshalSite)) {
            return marshaler;
        }
    }
    return null;
}
Also used : RefType(soot.RefType) ArrayType(soot.ArrayType) ArrayList(java.util.ArrayList) SootClass(soot.SootClass) HashSet(java.util.HashSet)

Example 22 with ArrayType

use of soot.ArrayType in project soot by Sable.

the class TypeNode method array.

public TypeNode array() {
    if (array != null) {
        return array;
    }
    if (type instanceof ArrayType) {
        ArrayType atype = (ArrayType) type;
        array = hierarchy.typeNode(ArrayType.v(atype.baseType, atype.numDimensions + 1));
        return array;
    }
    if (type instanceof PrimType || type instanceof RefType) {
        array = hierarchy.typeNode(ArrayType.v(type, 1));
        return array;
    }
    throw new InternalTypingException();
}
Also used : ArrayType(soot.ArrayType) RefType(soot.RefType) PrimType(soot.PrimType)

Example 23 with ArrayType

use of soot.ArrayType 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)

Example 24 with ArrayType

use of soot.ArrayType in project soot by Sable.

the class ConstraintChecker method caseAssignStmt.

public void caseAssignStmt(AssignStmt stmt) {
    Value l = stmt.getLeftOp();
    Value r = stmt.getRightOp();
    TypeNode left = null;
    TypeNode 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 ((base.numDimensions == 1) && (base.baseType instanceof IntegerType)) {
                left = ClassHierarchy.v().typeNode(base.baseType);
            }
            if (index instanceof Local) {
                if (!ClassHierarchy.v().typeNode(((Local) index).getType()).hasAncestor_1(ClassHierarchy.v().INT)) {
                    if (fix) {
                        ref.setIndex(insertCast((Local) index, IntType.v(), stmt));
                    } else {
                        error("Type Error(5)");
                    }
                }
            }
        }
    } else if (l instanceof Local) {
        if (((Local) l).getType() instanceof IntegerType) {
            left = ClassHierarchy.v().typeNode(((Local) l).getType());
        }
    } else if (l instanceof InstanceFieldRef) {
        InstanceFieldRef ref = (InstanceFieldRef) l;
        if (ref.getFieldRef().type() instanceof IntegerType) {
            left = ClassHierarchy.v().typeNode(ref.getFieldRef().type());
        }
    } else if (l instanceof StaticFieldRef) {
        StaticFieldRef ref = (StaticFieldRef) l;
        if (ref.getFieldRef().type() instanceof IntegerType) {
            left = ClassHierarchy.v().typeNode(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)) {
            ArrayType base = (ArrayType) baset;
            Value index = ref.getIndex();
            if ((base.numDimensions == 1) && (base.baseType instanceof IntegerType)) {
                right = ClassHierarchy.v().typeNode(base.baseType);
            }
            if (index instanceof Local) {
                if (!ClassHierarchy.v().typeNode(((Local) index).getType()).hasAncestor_1(ClassHierarchy.v().INT)) {
                    if (fix) {
                        ref.setIndex(insertCast((Local) index, IntType.v(), stmt));
                    } else {
                        error("Type Error(6)");
                    }
                }
            }
        }
    } else if (r instanceof DoubleConstant) {
    } else if (r instanceof FloatConstant) {
    } else if (r instanceof IntConstant) {
        int value = ((IntConstant) r).value;
        if (value < -32768) {
            right = ClassHierarchy.v().INT;
        } else if (value < -128) {
            right = ClassHierarchy.v().SHORT;
        } else if (value < 0) {
            right = ClassHierarchy.v().BYTE;
        } else if (value < 2) {
            right = ClassHierarchy.v().R0_1;
        } else if (value < 128) {
            right = ClassHierarchy.v().R0_127;
        } else if (value < 32768) {
            right = ClassHierarchy.v().R0_32767;
        } else if (value < 65536) {
            right = ClassHierarchy.v().CHAR;
        } else {
            right = ClassHierarchy.v().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();
        TypeNode lop = null;
        TypeNode rop = null;
        // ******** LEFT ********
        if (lv instanceof Local) {
            if (((Local) lv).getType() instanceof IntegerType) {
                lop = ClassHierarchy.v().typeNode(((Local) lv).getType());
            }
        } else if (lv instanceof DoubleConstant) {
        } else if (lv instanceof FloatConstant) {
        } else if (lv instanceof IntConstant) {
            int value = ((IntConstant) lv).value;
            if (value < -32768) {
                lop = ClassHierarchy.v().INT;
            } else if (value < -128) {
                lop = ClassHierarchy.v().SHORT;
            } else if (value < 0) {
                lop = ClassHierarchy.v().BYTE;
            } else if (value < 2) {
                lop = ClassHierarchy.v().R0_1;
            } else if (value < 128) {
                lop = ClassHierarchy.v().R0_127;
            } else if (value < 32768) {
                lop = ClassHierarchy.v().R0_32767;
            } else if (value < 65536) {
                lop = ClassHierarchy.v().CHAR;
            } else {
                lop = ClassHierarchy.v().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 = ClassHierarchy.v().typeNode(((Local) rv).getType());
            }
        } else if (rv instanceof DoubleConstant) {
        } else if (rv instanceof FloatConstant) {
        } else if (rv instanceof IntConstant) {
            int value = ((IntConstant) rv).value;
            if (value < -32768) {
                rop = ClassHierarchy.v().INT;
            } else if (value < -128) {
                rop = ClassHierarchy.v().SHORT;
            } else if (value < 0) {
                rop = ClassHierarchy.v().BYTE;
            } else if (value < 2) {
                rop = ClassHierarchy.v().R0_1;
            } else if (value < 128) {
                rop = ClassHierarchy.v().R0_127;
            } else if (value < 32768) {
                rop = ClassHierarchy.v().R0_32767;
            } else if (value < 65536) {
                rop = ClassHierarchy.v().CHAR;
            } else {
                rop = ClassHierarchy.v().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 MulExpr) || (be instanceof DivExpr) || (be instanceof RemExpr)) {
            if (lop != null && rop != null) {
                if (!lop.hasAncestor_1(ClassHierarchy.v().INT)) {
                    if (fix) {
                        be.setOp1(insertCast(be.getOp1(), getTypeForCast(lop), IntType.v(), stmt));
                    } else {
                        error("Type Error(7)");
                    }
                }
                if (!rop.hasAncestor_1(ClassHierarchy.v().INT)) {
                    if (fix) {
                        be.setOp2(insertCast(be.getOp2(), getTypeForCast(rop), IntType.v(), stmt));
                    } else {
                        error("Type Error(8)");
                    }
                }
            }
            right = ClassHierarchy.v().INT;
        } else if ((be instanceof AndExpr) || (be instanceof OrExpr) || (be instanceof XorExpr)) {
            if (lop != null && rop != null) {
                TypeNode lca = lop.lca_1(rop);
                if (lca == ClassHierarchy.v().TOP) {
                    if (fix) {
                        if (!lop.hasAncestor_1(ClassHierarchy.v().INT)) {
                            be.setOp1(insertCast(be.getOp1(), getTypeForCast(lop), getTypeForCast(rop), stmt));
                            lca = rop;
                        }
                        if (!rop.hasAncestor_1(ClassHierarchy.v().INT)) {
                            be.setOp2(insertCast(be.getOp2(), getTypeForCast(rop), getTypeForCast(lop), stmt));
                            lca = lop;
                        }
                    } else {
                        error("Type Error(11)");
                    }
                }
                right = lca;
            }
        } else if (be instanceof ShlExpr) {
            if (lop != null) {
                if (!lop.hasAncestor_1(ClassHierarchy.v().INT)) {
                    if (fix) {
                        be.setOp1(insertCast(be.getOp1(), getTypeForCast(lop), IntType.v(), stmt));
                    } else {
                        error("Type Error(9)");
                    }
                }
            }
            if (!rop.hasAncestor_1(ClassHierarchy.v().INT)) {
                if (fix) {
                    be.setOp2(insertCast(be.getOp2(), getTypeForCast(rop), IntType.v(), stmt));
                } else {
                    error("Type Error(10)");
                }
            }
            right = (lop == null) ? null : ClassHierarchy.v().INT;
        } else if ((be instanceof ShrExpr) || (be instanceof UshrExpr)) {
            if (lop != null) {
                if (!lop.hasAncestor_1(ClassHierarchy.v().INT)) {
                    if (fix) {
                        be.setOp1(insertCast(be.getOp1(), getTypeForCast(lop), ByteType.v(), stmt));
                        lop = ClassHierarchy.v().BYTE;
                    } else {
                        error("Type Error(9)");
                    }
                }
            }
            if (!rop.hasAncestor_1(ClassHierarchy.v().INT)) {
                if (fix) {
                    be.setOp2(insertCast(be.getOp2(), getTypeForCast(rop), IntType.v(), stmt));
                } else {
                    error("Type Error(10)");
                }
            }
            right = lop;
        } else if ((be instanceof CmpExpr) || (be instanceof CmpgExpr) || (be instanceof CmplExpr)) {
            right = ClassHierarchy.v().BYTE;
        } else if ((be instanceof EqExpr) || (be instanceof GeExpr) || (be instanceof GtExpr) || (be instanceof LeExpr) || (be instanceof LtExpr) || (be instanceof NeExpr)) {
            if (rop != null) {
                TypeNode lca = lop.lca_1(rop);
                if (lca == ClassHierarchy.v().TOP) {
                    if (fix) {
                        if (!lop.hasAncestor_1(ClassHierarchy.v().INT)) {
                            be.setOp1(insertCast(be.getOp1(), getTypeForCast(lop), getTypeForCast(rop), stmt));
                        }
                        if (!rop.hasAncestor_1(ClassHierarchy.v().INT)) {
                            be.setOp2(insertCast(be.getOp2(), getTypeForCast(rop), getTypeForCast(lop), stmt));
                        }
                    } else {
                        error("Type Error(11)");
                    }
                }
            }
            right = ClassHierarchy.v().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 = ClassHierarchy.v().typeNode(ce.getCastType());
        }
    } else if (r instanceof InstanceOfExpr) {
        right = ClassHierarchy.v().BOOLEAN;
    } else if (r instanceof InvokeExpr) {
        InvokeExpr ie = (InvokeExpr) r;
        handleInvokeExpr(ie, stmt);
        if (ie.getMethodRef().returnType() instanceof IntegerType) {
            right = ClassHierarchy.v().typeNode(ie.getMethodRef().returnType());
        }
    } else if (r instanceof NewArrayExpr) {
        NewArrayExpr nae = (NewArrayExpr) r;
        Value size = nae.getSize();
        if (size instanceof Local) {
            if (!ClassHierarchy.v().typeNode(((Local) size).getType()).hasAncestor_1(ClassHierarchy.v().INT)) {
                if (fix) {
                    nae.setSize(insertCast((Local) size, IntType.v(), stmt));
                } else {
                    error("Type Error(12)");
                }
            }
        }
    } else if (r instanceof NewExpr) {
    } else if (r instanceof NewMultiArrayExpr) {
        NewMultiArrayExpr nmae = (NewMultiArrayExpr) r;
        for (int i = 0; i < nmae.getSizeCount(); i++) {
            Value size = nmae.getSize(i);
            if (size instanceof Local) {
                if (!ClassHierarchy.v().typeNode(((Local) size).getType()).hasAncestor_1(ClassHierarchy.v().INT)) {
                    if (fix) {
                        nmae.setSize(i, insertCast((Local) size, IntType.v(), stmt));
                    } else {
                        error("Type Error(13)");
                    }
                }
            }
        }
    } else if (r instanceof LengthExpr) {
        right = ClassHierarchy.v().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) {
                TypeNode ltype = ClassHierarchy.v().typeNode(local.getType());
                if (!ltype.hasAncestor_1(ClassHierarchy.v().INT)) {
                    if (fix) {
                        ne.setOp(insertCast(local, IntType.v(), stmt));
                        ltype = ClassHierarchy.v().BYTE;
                    } else {
                        error("Type Error(14)");
                    }
                }
                right = (ltype == ClassHierarchy.v().CHAR) ? ClassHierarchy.v().INT : ltype;
            }
        } else if (ne.getOp() instanceof DoubleConstant) {
        } else if (ne.getOp() instanceof FloatConstant) {
        } else if (ne.getOp() instanceof IntConstant) {
            right = ClassHierarchy.v().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 = ClassHierarchy.v().typeNode(local.getType());
        }
    } else if (r instanceof InstanceFieldRef) {
        InstanceFieldRef ref = (InstanceFieldRef) r;
        if (ref.getFieldRef().type() instanceof IntegerType) {
            right = ClassHierarchy.v().typeNode(ref.getFieldRef().type());
        }
    } else if (r instanceof StaticFieldRef) {
        StaticFieldRef ref = (StaticFieldRef) r;
        if (ref.getFieldRef().type() instanceof IntegerType) {
            right = ClassHierarchy.v().typeNode(ref.getFieldRef().type());
        }
    } else {
        throw new RuntimeException("Unhandled assignment right hand side type: " + r.getClass());
    }
    if (left != null && right != null) {
        if (!right.hasAncestor_1(left)) {
            if (fix) {
                stmt.setRightOp(insertCast(stmt.getRightOp(), getTypeForCast(right), getTypeForCast(left), stmt));
            } else {
                error("Type Error(15)");
            }
        }
    }
}
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) ShortType(soot.ShortType) BooleanType(soot.BooleanType) ByteType(soot.ByteType) Type(soot.Type) IntType(soot.IntType) 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 25 with ArrayType

use of soot.ArrayType in project soot by Sable.

the class BytecodeHierarchy method lcas_.

public static Collection<Type> lcas_(Type a, Type b) {
    if (TypeResolver.typesEqual(a, b))
        return Collections.<Type>singletonList(a);
    else if (a instanceof BottomType)
        return Collections.<Type>singletonList(b);
    else if (b instanceof BottomType)
        return Collections.<Type>singletonList(a);
    else if (a instanceof IntegerType && b instanceof IntegerType)
        return Collections.<Type>singletonList(IntType.v());
    else // Implicit type widening: Integer+Float -> Float
    if (a instanceof IntegerType && b instanceof FloatType)
        return Collections.<Type>singletonList(FloatType.v());
    else if (b instanceof IntegerType && a instanceof FloatType)
        return Collections.<Type>singletonList(FloatType.v());
    else // Disallow type sharing for primitives in general
    if (a instanceof PrimType || b instanceof PrimType)
        return Collections.<Type>emptyList();
    else // Null reference handling
    if (a instanceof NullType)
        return Collections.<Type>singletonList(b);
    else if (b instanceof NullType)
        return Collections.<Type>singletonList(a);
    else // a and b are both ArrayType or RefType
    if (a instanceof ArrayType && b instanceof ArrayType) {
        Type eta = ((ArrayType) a).getElementType(), etb = ((ArrayType) b).getElementType();
        Collection<Type> ts;
        // Primitive arrays are not covariant but all other arrays are
        if (eta instanceof PrimType || etb instanceof PrimType)
            ts = Collections.<Type>emptyList();
        else
            ts = lcas_(eta, etb);
        LinkedList<Type> r = new LinkedList<Type>();
        if (ts.isEmpty()) {
            // From Java Language Spec 2nd ed., Chapter 10, Arrays
            r.add(RefType.v("java.lang.Object"));
            r.add(RefType.v("java.io.Serializable"));
            r.add(RefType.v("java.lang.Cloneable"));
        } else
            for (Type t : ts) r.add(t.makeArrayType());
        return r;
    } else if (a instanceof ArrayType || b instanceof ArrayType) {
        Type rt;
        if (a instanceof ArrayType)
            rt = b;
        else
            rt = a;
        /* If the reference type implements Serializable or Cloneable then 
			these are the least common supertypes, otherwise the only one is 
			Object. */
        LinkedList<Type> r = new LinkedList<Type>();
        /* Do not consider Object to be a subtype of Serializable or Cloneable
			(it can appear this way if phantom-refs is enabled and rt.jar is not
			available) otherwise an infinite loop can result. */
        if (!TypeResolver.typesEqual(RefType.v("java.lang.Object"), rt)) {
            if (ancestor_(RefType.v("java.io.Serializable"), rt))
                r.add(RefType.v("java.io.Serializable"));
            if (ancestor_(RefType.v("java.lang.Cloneable"), rt))
                r.add(RefType.v("java.lang.Cloneable"));
        }
        if (r.isEmpty())
            r.add(RefType.v("java.lang.Object"));
        return r;
    } else // a and b are both RefType
    {
        Collection<AncestryTreeNode> treea = buildAncestryTree((RefType) a), treeb = buildAncestryTree((RefType) b);
        LinkedList<Type> r = new LinkedList<Type>();
        for (AncestryTreeNode nodea : treea) for (AncestryTreeNode nodeb : treeb) {
            RefType t = leastCommonNode(nodea, nodeb);
            boolean least = true;
            for (ListIterator<Type> i = r.listIterator(); i.hasNext(); ) {
                Type t_ = i.next();
                if (ancestor_(t, t_)) {
                    least = false;
                    break;
                }
                if (ancestor_(t_, t))
                    i.remove();
            }
            if (least)
                r.add(t);
        }
        // syed - 05/06/2009
        if (r.isEmpty())
            r.add(RefType.v("java.lang.Object"));
        return r;
    }
}
Also used : ListIterator(java.util.ListIterator) LinkedList(java.util.LinkedList) FloatType(soot.FloatType) IntegerType(soot.IntegerType) ArrayType(soot.ArrayType) RefType(soot.RefType) RefType(soot.RefType) ArrayType(soot.ArrayType) FloatType(soot.FloatType) IntegerType(soot.IntegerType) IntType(soot.IntType) Type(soot.Type) PrimType(soot.PrimType) NullType(soot.NullType) PrimType(soot.PrimType) Collection(java.util.Collection) NullType(soot.NullType)

Aggregations

ArrayType (soot.ArrayType)44 Type (soot.Type)34 RefType (soot.RefType)26 Local (soot.Local)19 Value (soot.Value)18 IntType (soot.IntType)17 BooleanType (soot.BooleanType)14 NewArrayExpr (soot.jimple.NewArrayExpr)13 ByteType (soot.ByteType)12 FloatType (soot.FloatType)12 NullType (soot.NullType)12 ShortType (soot.ShortType)12 ArrayRef (soot.jimple.ArrayRef)12 CharType (soot.CharType)11 DoubleType (soot.DoubleType)11 LongType (soot.LongType)11 AssignStmt (soot.jimple.AssignStmt)11 SootClass (soot.SootClass)10 InvokeExpr (soot.jimple.InvokeExpr)10 PrimType (soot.PrimType)9