use of soot.NullType 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)");
}
}
}
}
use of soot.NullType in project soot by Sable.
the class TypeResolver method assign_types_1_2.
private void assign_types_1_2() throws TypeException {
for (Iterator<Local> localIt = stmtBody.getLocals().iterator(); localIt.hasNext(); ) {
final Local local = localIt.next();
TypeVariable var = typeVariable(local);
if (var == null) {
local.setType(RefType.v("java.lang.Object"));
} else if (var.depth() == 0) {
if (var.type() == null) {
TypeVariable.error("Type Error(5): Variable without type");
} else {
local.setType(var.type().type());
}
} else {
TypeVariable element = var.element();
for (int j = 1; j < var.depth(); j++) {
element = element.element();
}
if (element.type() == null) {
TypeVariable.error("Type Error(6): Array variable without base type");
} else if (element.type().type() instanceof NullType) {
local.setType(NullType.v());
} else {
Type t = element.type().type();
if (t instanceof IntType) {
local.setType(var.approx().type());
} else {
local.setType(ArrayType.v(t, var.depth()));
}
}
}
if (DEBUG) {
if ((var != null) && (var.approx() != null) && (var.approx().type() != null) && (local != null) && (local.getType() != null) && !local.getType().equals(var.approx().type())) {
logger.debug("local: " + local + ", type: " + local.getType() + ", approx: " + var.approx().type());
}
}
}
}
use of soot.NullType 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;
}
}
use of soot.NullType in project soot by Sable.
the class ExprVisitor method castPrimitive.
private void castPrimitive(Register sourceReg, Value source, Type castSootType) {
PrimitiveType castType = PrimitiveType.getByName(castSootType.toString());
// than sorry and it's easy to fix it here.
if (castType == PrimitiveType.INT && source.getType() instanceof NullType)
source = IntConstant.v(0);
// select fitting conversion opcode, depending on the source and cast
// type
Type srcType = source.getType();
if (srcType instanceof RefType)
throw new RuntimeException("Trying to cast reference type " + srcType + " to a primitive");
PrimitiveType sourceType = PrimitiveType.getByName(srcType.toString());
if (castType == PrimitiveType.BOOLEAN) {
// there is no "-to-boolean" opcode, so just pretend to move an int
// to an int
castType = PrimitiveType.INT;
sourceType = PrimitiveType.INT;
}
if (shouldCastFromInt(sourceType, castType)) {
// pretend to cast from int since that is OK
sourceType = PrimitiveType.INT;
Opcode opc = getCastOpc(sourceType, castType);
stmtV.addInsn(new Insn12x(opc, destinationReg, sourceReg), origStmt);
} else if (isMoveCompatible(sourceType, castType)) {
/*
* no actual cast needed, just move the reg content if regs differ
*/
if (destinationReg.getNumber() != sourceReg.getNumber()) {
stmtV.addInsn(StmtVisitor.buildMoveInsn(destinationReg, sourceReg), origStmt);
} else // one for jumps
if (!origStmt.getBoxesPointingToThis().isEmpty())
stmtV.addInsn(new Insn10x(Opcode.NOP), origStmt);
} else if (needsCastThroughInt(sourceType, castType)) {
/*
* an unsupported "dest = (cast) src" is broken down to
* "tmp = (int) src" and "dest = (cast) tmp", using a tmp reg to not
* mess with the original reg types
*/
Opcode castToIntOpc = getCastOpc(sourceType, PrimitiveType.INT);
Opcode castFromIntOpc = getCastOpc(PrimitiveType.INT, castType);
Register tmp = regAlloc.asTmpReg(IntType.v());
stmtV.addInsn(new Insn12x(castToIntOpc, tmp, sourceReg), origStmt);
stmtV.addInsn(new Insn12x(castFromIntOpc, destinationReg, tmp.clone()), origStmt);
} else {
// the leftover simple cases, where we just cast as stated
Opcode opc = getCastOpc(sourceType, castType);
stmtV.addInsn(new Insn12x(opc, destinationReg, sourceReg), origStmt);
}
}
use of soot.NullType in project soot by Sable.
the class AbstractThrowAnalysis method mightThrowExplicitly.
public ThrowableSet mightThrowExplicitly(ThrowStmt t) {
Value thrownExpression = t.getOp();
Type thrownType = thrownExpression.getType();
if (thrownType == null || thrownType instanceof UnknownType) {
// We can't identify the type of thrownExpression, so...
return ThrowableSet.Manager.v().ALL_THROWABLES;
} else if (thrownType instanceof NullType) {
ThrowableSet result = ThrowableSet.Manager.v().EMPTY;
result = result.add(ThrowableSet.Manager.v().NULL_POINTER_EXCEPTION);
return result;
} else if (!(thrownType instanceof RefType)) {
throw new IllegalStateException("UnitThrowAnalysis StmtSwitch: type of throw argument is not a RefType!");
} else {
ThrowableSet result = ThrowableSet.Manager.v().EMPTY;
if (thrownExpression instanceof NewInvokeExpr) {
// In this case, we know the exact type of the
// argument exception.
result = result.add((RefType) thrownType);
} else {
result = result.add(AnySubType.v((RefType) thrownType));
}
return result;
}
}
Aggregations