use of soot.jimple.ThrowStmt in project soot by Sable.
the class UnitThrowAnalysisTest method testJThrowStmt.
@Test
public void testJThrowStmt() {
// First test with an argument that is included in
// PERENNIAL_THROW_EXCEPTIONS.
ThrowStmt s = Jimple.v().newThrowStmt(Jimple.v().newLocal("local0", RefType.v("java.lang.NullPointerException")));
Set expectedRep = new ExceptionHashSet(utility.PERENNIAL_THROW_EXCEPTIONS);
expectedRep.remove(utility.NULL_POINTER_EXCEPTION);
expectedRep.add(AnySubType.v(utility.NULL_POINTER_EXCEPTION));
assertTrue(ExceptionTestUtility.sameMembers(expectedRep, Collections.EMPTY_SET, unitAnalysis.mightThrow(s)));
assertEquals(utility.PERENNIAL_THROW_EXCEPTIONS_PLUS_SUPERTYPES, utility.catchableSubset(unitAnalysis.mightThrow(s)));
// Throw a local of type IncompatibleClassChangeError.
Local local = Jimple.v().newLocal("local1", utility.INCOMPATIBLE_CLASS_CHANGE_ERROR);
s.setOp(local);
expectedRep = new ExceptionHashSet(utility.THROW_PLUS_INCOMPATIBLE_CLASS_CHANGE);
expectedRep.remove(utility.INCOMPATIBLE_CLASS_CHANGE_ERROR);
expectedRep.add(AnySubType.v(utility.INCOMPATIBLE_CLASS_CHANGE_ERROR));
assertTrue(ExceptionTestUtility.sameMembers(expectedRep, Collections.EMPTY_SET, unitAnalysis.mightThrow(s)));
assertEquals(utility.THROW_PLUS_INCOMPATIBLE_CLASS_CHANGE_PLUS_SUBTYPES_PLUS_SUPERTYPES, utility.catchableSubset(unitAnalysis.mightThrow(s)));
// Throw a local of unknown type.
local = Jimple.v().newLocal("local1", soot.UnknownType.v());
s.setOp(local);
assertTrue(ExceptionTestUtility.sameMembers(utility.ALL_THROWABLES_REP, Collections.EMPTY_SET, unitAnalysis.mightThrow(s)));
assertEquals(utility.ALL_TEST_THROWABLES, utility.catchableSubset(unitAnalysis.mightThrow(s)));
}
use of soot.jimple.ThrowStmt in project soot by Sable.
the class UnitThrowAnalysisTest method testGThrowStmt.
@Test
public void testGThrowStmt() {
ThrowStmt s = Grimp.v().newThrowStmt(Grimp.v().newLocal("local0", RefType.v("java.util.zip.ZipException")));
Set expectedRep = new ExceptionHashSet(utility.PERENNIAL_THROW_EXCEPTIONS);
expectedRep.add(AnySubType.v(Scene.v().getRefType("java.util.zip.ZipException")));
assertTrue(ExceptionTestUtility.sameMembers(expectedRep, Collections.EMPTY_SET, unitAnalysis.mightThrow(s)));
Set expectedCatch = new ExceptionHashSet(utility.PERENNIAL_THROW_EXCEPTIONS_PLUS_SUPERTYPES);
// We don't need to add java.util.zip.ZipException, since it is not
// in the universe of test Throwables.
assertEquals(expectedCatch, utility.catchableSubset(unitAnalysis.mightThrow(s)));
// Now throw a new IncompatibleClassChangeError.
s = Grimp.v().newThrowStmt(Grimp.v().newNewInvokeExpr(utility.INCOMPATIBLE_CLASS_CHANGE_ERROR, Scene.v().makeMethodRef(utility.INCOMPATIBLE_CLASS_CHANGE_ERROR.getSootClass(), "void <init>", Collections.EMPTY_LIST, VoidType.v(), false), new ArrayList()));
assertTrue(ExceptionTestUtility.sameMembers(utility.THROW_PLUS_INCOMPATIBLE_CLASS_CHANGE, Collections.EMPTY_SET, unitAnalysis.mightThrow(s)));
assertEquals(utility.THROW_PLUS_INCOMPATIBLE_CLASS_CHANGE_PLUS_SUPERTYPES, utility.catchableSubset(unitAnalysis.mightThrow(s)));
// Throw a local of type IncompatibleClassChangeError.
Local local = Grimp.v().newLocal("local1", utility.INCOMPATIBLE_CLASS_CHANGE_ERROR);
s.setOp(local);
expectedRep = new ExceptionHashSet(utility.PERENNIAL_THROW_EXCEPTIONS);
expectedRep.remove(utility.INCOMPATIBLE_CLASS_CHANGE_ERROR);
expectedRep.add(AnySubType.v(utility.INCOMPATIBLE_CLASS_CHANGE_ERROR));
assertTrue(ExceptionTestUtility.sameMembers(expectedRep, Collections.EMPTY_SET, unitAnalysis.mightThrow(s)));
assertEquals(utility.THROW_PLUS_INCOMPATIBLE_CLASS_CHANGE_PLUS_SUBTYPES_PLUS_SUPERTYPES, utility.catchableSubset(unitAnalysis.mightThrow(s)));
// Throw a local of unknown type.
local = Jimple.v().newLocal("local1", soot.UnknownType.v());
s.setOp(local);
assertTrue(ExceptionTestUtility.sameMembers(utility.ALL_THROWABLES_REP, Collections.EMPTY_SET, unitAnalysis.mightThrow(s)));
assertEquals(utility.ALL_TEST_THROWABLES, utility.catchableSubset(unitAnalysis.mightThrow(s)));
}
use of soot.jimple.ThrowStmt in project soot by Sable.
the class DexIfTransformer method internalTransform.
@Override
protected void internalTransform(final Body body, String phaseName, Map<String, String> options) {
final DexDefUseAnalysis localDefs = new DexDefUseAnalysis(body);
Set<IfStmt> ifSet = getNullIfCandidates(body);
for (IfStmt ifs : ifSet) {
ConditionExpr ifCondition = (ConditionExpr) ifs.getCondition();
Local[] twoIfLocals = new Local[] { (Local) ifCondition.getOp1(), (Local) ifCondition.getOp2() };
usedAsObject = false;
for (Local loc : twoIfLocals) {
Set<Unit> defs = localDefs.collectDefinitionsWithAliases(loc);
// process normally
doBreak = false;
for (Unit u : defs) {
// put correct local in l
if (u instanceof DefinitionStmt) {
l = (Local) ((DefinitionStmt) u).getLeftOp();
} else {
throw new RuntimeException("ERROR: def can not be something else than Assign or Identity statement! (def: " + u + " class: " + u.getClass() + "");
}
// check defs
u.apply(new // Alex: should also end
AbstractStmtSwitch() {
// as soon as detected
// as not used as an
// object
@Override
public void caseAssignStmt(AssignStmt stmt) {
Value r = stmt.getRightOp();
if (r instanceof FieldRef) {
usedAsObject = isObject(((FieldRef) r).getFieldRef().type());
if (usedAsObject)
doBreak = true;
return;
} else if (r instanceof ArrayRef) {
ArrayRef ar = (ArrayRef) r;
if (ar.getType() instanceof UnknownType) {
// isObject
usedAsObject = stmt.hasTag("ObjectOpTag");
// (findArrayType
// (g,
// localDefs,
// localUses,
// stmt));
} else {
usedAsObject = isObject(ar.getType());
}
if (usedAsObject)
doBreak = true;
return;
} else if (r instanceof StringConstant || r instanceof NewExpr || r instanceof NewArrayExpr) {
usedAsObject = true;
if (usedAsObject)
doBreak = true;
return;
} else if (r instanceof CastExpr) {
usedAsObject = isObject(((CastExpr) r).getCastType());
if (usedAsObject)
doBreak = true;
return;
} else if (r instanceof InvokeExpr) {
usedAsObject = isObject(((InvokeExpr) r).getType());
if (usedAsObject)
doBreak = true;
return;
} else if (r instanceof LengthExpr) {
usedAsObject = false;
if (usedAsObject)
doBreak = true;
return;
}
}
@Override
public void caseIdentityStmt(IdentityStmt stmt) {
if (stmt.getLeftOp() == l) {
usedAsObject = isObject(stmt.getRightOp().getType());
if (usedAsObject)
doBreak = true;
return;
}
}
});
if (doBreak)
break;
// check uses
for (Unit use : localDefs.getUsesOf(l)) {
use.apply(new AbstractStmtSwitch() {
private boolean examineInvokeExpr(InvokeExpr e) {
List<Value> args = e.getArgs();
List<Type> argTypes = e.getMethodRef().parameterTypes();
assert args.size() == argTypes.size();
for (int i = 0; i < args.size(); i++) {
if (args.get(i) == l && isObject(argTypes.get(i))) {
return true;
}
}
// check for base
SootMethodRef sm = e.getMethodRef();
if (!sm.isStatic()) {
if (e instanceof AbstractInvokeExpr) {
AbstractInstanceInvokeExpr aiiexpr = (AbstractInstanceInvokeExpr) e;
Value b = aiiexpr.getBase();
if (b == l) {
return true;
}
}
}
return false;
}
@Override
public void caseInvokeStmt(InvokeStmt stmt) {
InvokeExpr e = stmt.getInvokeExpr();
usedAsObject = examineInvokeExpr(e);
if (usedAsObject)
doBreak = true;
return;
}
@Override
public void caseAssignStmt(AssignStmt stmt) {
Value left = stmt.getLeftOp();
Value r = stmt.getRightOp();
if (left instanceof ArrayRef) {
if (((ArrayRef) left).getIndex() == l) {
// doBreak = true;
return;
}
}
// used to assign
if (stmt.getRightOp() == l) {
Value l = stmt.getLeftOp();
if (l instanceof StaticFieldRef && isObject(((StaticFieldRef) l).getFieldRef().type())) {
usedAsObject = true;
if (usedAsObject)
doBreak = true;
return;
} else if (l instanceof InstanceFieldRef && isObject(((InstanceFieldRef) l).getFieldRef().type())) {
usedAsObject = true;
if (usedAsObject)
doBreak = true;
return;
} else if (l instanceof ArrayRef) {
Type aType = ((ArrayRef) l).getType();
if (aType instanceof UnknownType) {
// isObject(
usedAsObject = stmt.hasTag("ObjectOpTag");
// findArrayType(g,
// localDefs,
// localUses,
// stmt));
} else {
usedAsObject = isObject(aType);
}
if (usedAsObject)
doBreak = true;
return;
}
}
// assignment)
if (r instanceof FieldRef) {
// isObject(((FieldRef)
usedAsObject = true;
// r).getFieldRef().type());
if (usedAsObject)
doBreak = true;
return;
} else if (r instanceof ArrayRef) {
ArrayRef ar = (ArrayRef) r;
if (ar.getBase() == l) {
usedAsObject = true;
} else {
// used as index
usedAsObject = false;
}
if (usedAsObject)
doBreak = true;
return;
} else if (r instanceof StringConstant || r instanceof NewExpr) {
throw new RuntimeException("NOT POSSIBLE StringConstant or NewExpr at " + stmt);
} else if (r instanceof NewArrayExpr) {
usedAsObject = false;
if (usedAsObject)
doBreak = true;
return;
} else if (r instanceof CastExpr) {
usedAsObject = isObject(((CastExpr) r).getCastType());
if (usedAsObject)
doBreak = true;
return;
} else if (r instanceof InvokeExpr) {
usedAsObject = examineInvokeExpr((InvokeExpr) stmt.getRightOp());
if (usedAsObject)
doBreak = true;
return;
} else if (r instanceof LengthExpr) {
usedAsObject = true;
if (usedAsObject)
doBreak = true;
return;
} else if (r instanceof BinopExpr) {
usedAsObject = false;
if (usedAsObject)
doBreak = true;
return;
}
}
@Override
public void caseIdentityStmt(IdentityStmt stmt) {
if (stmt.getLeftOp() == l)
throw new RuntimeException("IMPOSSIBLE 0");
}
@Override
public void caseEnterMonitorStmt(EnterMonitorStmt stmt) {
usedAsObject = stmt.getOp() == l;
if (usedAsObject)
doBreak = true;
return;
}
@Override
public void caseExitMonitorStmt(ExitMonitorStmt stmt) {
usedAsObject = stmt.getOp() == l;
if (usedAsObject)
doBreak = true;
return;
}
@Override
public void caseReturnStmt(ReturnStmt stmt) {
usedAsObject = stmt.getOp() == l && isObject(body.getMethod().getReturnType());
if (usedAsObject)
doBreak = true;
return;
}
@Override
public void caseThrowStmt(ThrowStmt stmt) {
usedAsObject = stmt.getOp() == l;
if (usedAsObject)
doBreak = true;
return;
}
});
if (doBreak)
break;
}
// for uses
if (doBreak)
break;
}
if (// as soon as one def or use refers to an object
doBreak)
// be updated
break;
}
// change values
if (usedAsObject) {
Set<Unit> defsOp1 = localDefs.collectDefinitionsWithAliases(twoIfLocals[0]);
Set<Unit> defsOp2 = localDefs.collectDefinitionsWithAliases(twoIfLocals[1]);
defsOp1.addAll(defsOp2);
for (Unit u : defsOp1) {
Stmt s = (Stmt) u;
// If we have a[x] = 0 and a is an object, we may not conclude 0 -> null
if (!s.containsArrayRef() || (!defsOp1.contains(s.getArrayRef().getBase()) && !defsOp2.contains(s.getArrayRef().getBase())))
replaceWithNull(u);
Local l = (Local) ((DefinitionStmt) u).getLeftOp();
for (Unit uuse : localDefs.getUsesOf(l)) {
Stmt use = (Stmt) uuse;
// If we have a[x] = 0 and a is an object, we may not conclude 0 -> null
if (!use.containsArrayRef() || (twoIfLocals[0] != use.getArrayRef().getBase()) && twoIfLocals[1] != use.getArrayRef().getBase())
replaceWithNull(use);
}
}
}
// end if
}
// for if statements
}
use of soot.jimple.ThrowStmt in project soot by Sable.
the class DalvikTyper method typeUntypedConstrantInDiv.
// this is needed because UnuesedStatementTransformer checks types in the div expressions
public void typeUntypedConstrantInDiv(final Body b) {
for (Unit u : b.getUnits()) {
StmtSwitch sw = new StmtSwitch() {
@Override
public void caseBreakpointStmt(BreakpointStmt stmt) {
// TODO Auto-generated method stub
}
@Override
public void caseInvokeStmt(InvokeStmt stmt) {
changeUntypedConstantsInInvoke(stmt.getInvokeExpr());
}
@Override
public void caseAssignStmt(AssignStmt stmt) {
if (stmt.getRightOp() instanceof NewArrayExpr) {
NewArrayExpr nae = (NewArrayExpr) stmt.getRightOp();
if (nae.getSize() instanceof UntypedConstant) {
UntypedIntOrFloatConstant uc = (UntypedIntOrFloatConstant) nae.getSize();
nae.setSize(uc.defineType(IntType.v()));
}
} else if (stmt.getRightOp() instanceof InvokeExpr) {
changeUntypedConstantsInInvoke((InvokeExpr) stmt.getRightOp());
} else if (stmt.getRightOp() instanceof CastExpr) {
CastExpr ce = (CastExpr) stmt.getRightOp();
if (ce.getOp() instanceof UntypedConstant) {
UntypedConstant uc = (UntypedConstant) ce.getOp();
// check incoming primitive type
for (Tag t : stmt.getTags()) {
// Debug.printDbg("assign primitive type from stmt tag: ", stmt, t);
if (t instanceof IntOpTag) {
ce.setOp(uc.defineType(IntType.v()));
return;
} else if (t instanceof FloatOpTag) {
ce.setOp(uc.defineType(FloatType.v()));
return;
} else if (t instanceof DoubleOpTag) {
ce.setOp(uc.defineType(DoubleType.v()));
return;
} else if (t instanceof LongOpTag) {
ce.setOp(uc.defineType(LongType.v()));
return;
}
}
// 0 -> null
ce.setOp(uc.defineType(RefType.v("java.lang.Object")));
}
}
if (stmt.containsArrayRef()) {
ArrayRef ar = stmt.getArrayRef();
if ((ar.getIndex() instanceof UntypedConstant)) {
UntypedIntOrFloatConstant uc = (UntypedIntOrFloatConstant) ar.getIndex();
ar.setIndex(uc.toIntConstant());
}
}
Value r = stmt.getRightOp();
if (r instanceof DivExpr || r instanceof RemExpr) {
// DivExpr de = (DivExpr) r;
for (Tag t : stmt.getTags()) {
// Debug.printDbg("div stmt tag: ", stmt, t);
if (t instanceof IntOpTag) {
checkExpr(r, IntType.v());
return;
} else if (t instanceof FloatOpTag) {
checkExpr(r, FloatType.v());
return;
} else if (t instanceof DoubleOpTag) {
checkExpr(r, DoubleType.v());
return;
} else if (t instanceof LongOpTag) {
checkExpr(r, LongType.v());
return;
}
}
}
}
@Override
public void caseIdentityStmt(IdentityStmt stmt) {
// TODO Auto-generated method stub
}
@Override
public void caseEnterMonitorStmt(EnterMonitorStmt stmt) {
// TODO Auto-generated method stub
}
@Override
public void caseExitMonitorStmt(ExitMonitorStmt stmt) {
// TODO Auto-generated method stub
}
@Override
public void caseGotoStmt(GotoStmt stmt) {
// TODO Auto-generated method stub
}
@Override
public void caseIfStmt(IfStmt stmt) {
// TODO Auto-generated method stub
}
@Override
public void caseLookupSwitchStmt(LookupSwitchStmt stmt) {
// TODO Auto-generated method stub
}
@Override
public void caseNopStmt(NopStmt stmt) {
// TODO Auto-generated method stub
}
@Override
public void caseRetStmt(RetStmt stmt) {
// TODO Auto-generated method stub
}
@Override
public void caseReturnStmt(ReturnStmt stmt) {
if (stmt.getOp() instanceof UntypedConstant) {
UntypedConstant uc = (UntypedConstant) stmt.getOp();
Type type = b.getMethod().getReturnType();
stmt.setOp(uc.defineType(type));
}
}
@Override
public void caseReturnVoidStmt(ReturnVoidStmt stmt) {
// TODO Auto-generated method stub
}
@Override
public void caseTableSwitchStmt(TableSwitchStmt stmt) {
// TODO Auto-generated method stub
}
@Override
public void caseThrowStmt(ThrowStmt stmt) {
if (stmt.getOp() instanceof UntypedConstant) {
UntypedConstant uc = (UntypedConstant) stmt.getOp();
stmt.setOp(uc.defineType(RefType.v("java.lang.Object")));
}
}
@Override
public void defaultCase(Object obj) {
// TODO Auto-generated method stub
}
};
u.apply(sw);
}
}
Aggregations