diff --git a/src/main/java/soot/dexpler/DexBody.java b/src/main/java/soot/dexpler/DexBody.java index 9e97905c6a7..4eb5ebd1d45 100755 --- a/src/main/java/soot/dexpler/DexBody.java +++ b/src/main/java/soot/dexpler/DexBody.java @@ -722,7 +722,6 @@ public Body jimplify(Body b, SootMethod m) { handleKnownDexTypes(b, jimple); new SharedInitializationLocalSplitter(DalvikThrowAnalysis.v()).transform(jBody); - // split first to find undefined uses getLocalSplitter().transform(jBody); @@ -820,12 +819,17 @@ public Body jimplify(Body b, SootMethod m) { } } + getLocalSplitter().transform(jBody); + new soot.jimple.toolkits.typing.fast.TypeResolver(jBody) { protected soot.jimple.toolkits.typing.fast.TypePromotionUseVisitor createTypePromotionUseVisitor(JimpleBody jb, soot.jimple.toolkits.typing.fast.Typing tg) { return new TypePromotionUseVisitor(jb, tg) { protected boolean allowConversion(Type ancestor, Type child) { + if (ancestor == child) { + return true; + } if ((ancestor instanceof IntegerType || ancestor instanceof FloatType) && (child instanceof IntegerType || child instanceof FloatType)) { return true; diff --git a/src/main/java/soot/jimple/toolkits/typing/fast/TypePromotionUseVisitor.java b/src/main/java/soot/jimple/toolkits/typing/fast/TypePromotionUseVisitor.java index 9970d066919..b72dbf76696 100644 --- a/src/main/java/soot/jimple/toolkits/typing/fast/TypePromotionUseVisitor.java +++ b/src/main/java/soot/jimple/toolkits/typing/fast/TypePromotionUseVisitor.java @@ -97,7 +97,12 @@ public Value visit(Value op, Type useType, Stmt stmt, boolean checkOnly) { return op; } - Type t = AugEvalFunction.eval_(this.tg, op, stmt, this.jb); + final Type t = AugEvalFunction.eval_(this.tg, op, stmt, this.jb); + final boolean eqType = TypeResolver.typesEqual(t, useType); + if (eqType) { + //shortcut + return op; + } if (!allowConversion(useType, t)) { logger.error(String.format("Failed Typing in %s at statement %s: Is not cast compatible: %s <-- %s", @@ -106,7 +111,7 @@ public Value visit(Value op, Type useType, Stmt stmt, boolean checkOnly) { } else if (!checkOnly && op instanceof Local && (t instanceof Integer1Type || t instanceof Integer127Type || t instanceof Integer32767Type || t instanceof WeakObjectType)) { Local v = (Local) op; - if (!TypeResolver.typesEqual(t, useType)) { + if (!eqType) { Type t_ = this.promote(t, useType); if (!TypeResolver.typesEqual(t, t_)) { this.tg.set(v, t_); diff --git a/src/main/java/soot/jimple/toolkits/typing/fast/TypeResolver.java b/src/main/java/soot/jimple/toolkits/typing/fast/TypeResolver.java index ec92ceba04f..2491c0ea6a5 100644 --- a/src/main/java/soot/jimple/toolkits/typing/fast/TypeResolver.java +++ b/src/main/java/soot/jimple/toolkits/typing/fast/TypeResolver.java @@ -33,6 +33,8 @@ import java.util.HashMap; import java.util.Iterator; import java.util.List; +import java.util.Map; +import java.util.Map.Entry; import java.util.Set; import soot.ArrayType; @@ -83,6 +85,7 @@ public class TypeResolver { private final List assignments; private final HashMap depends; + private final Set singleAssignments; private final LocalGenerator localGenerator; public TypeResolver(JimpleBody jb) { @@ -90,6 +93,31 @@ public TypeResolver(JimpleBody jb) { this.assignments = new ArrayList(); this.depends = new HashMap(jb.getLocalCount()); this.localGenerator = Scene.v().createLocalGenerator(jb); + Map map = new HashMap<>(); + for (Unit stmt : this.jb.getUnits()) { + if (stmt instanceof DefinitionStmt) { + DefinitionStmt def = (DefinitionStmt) stmt; + + Value lhs = def.getLeftOp(); + if (lhs instanceof Local) { + Local l = (Local) lhs; + Integer c = map.get(l); + if (c == null) { + c = 0; + } + c++; + map.put(l, c); + } + } + } + Iterator> t = map.entrySet().iterator(); + while (t.hasNext()) { + if (t.next().getValue() > 1) { + t.remove(); + } + } + this.singleAssignments = map.keySet(); + this.initAssignments(); } @@ -504,6 +532,28 @@ protected Collection applyAssignmentConstraints(Typing tg, IEvalFunction wl.set(0, numAssignments); sigma.add(new WorklistElement(tg, wl, new TypeDecision())); + if (tg.map.isEmpty()) { + //First get the easy cases out of the way. + for (int i = 0; i < numAssignments; i++) { + final DefinitionStmt stmt = this.assignments.get(i); + Value lhs = stmt.getLeftOp(); + if (lhs instanceof Local) { + Local v = (Local) lhs; + if (singleAssignments.contains(v)) { + Collection d = ef.eval(tg, stmt.getRightOp(), stmt); + if (d.size() == 1) { + Type t_ = d.iterator().next(); + d = reduceToAllowedTypesForLocal(Collections.singleton(t_), v); + if (d.size() == 1) { + tg.set(v, d.iterator().next()); + wl.clear(i); + } + } + } + } + } + } + Set throwable = null; while (!sigma.isEmpty()) { diff --git a/src/main/java/soot/jimple/toolkits/typing/fast/Typing.java b/src/main/java/soot/jimple/toolkits/typing/fast/Typing.java index eaf41b03da3..1435a3564ae 100644 --- a/src/main/java/soot/jimple/toolkits/typing/fast/Typing.java +++ b/src/main/java/soot/jimple/toolkits/typing/fast/Typing.java @@ -29,6 +29,7 @@ import java.util.Map; import soot.Local; +import soot.NullType; import soot.Type; /** @@ -56,7 +57,7 @@ public Type get(Local v) { } public Type set(Local v, Type t) { - return (t instanceof BottomType) ? null : this.map.put(v, t); + return (t instanceof BottomType || t instanceof NullType) ? null : this.map.put(v, t); } public Collection getAllLocals() { diff --git a/src/main/java/soot/toolkits/scalar/SharedInitializationLocalSplitter.java b/src/main/java/soot/toolkits/scalar/SharedInitializationLocalSplitter.java index e53f7817b4f..df9e196be71 100644 --- a/src/main/java/soot/toolkits/scalar/SharedInitializationLocalSplitter.java +++ b/src/main/java/soot/toolkits/scalar/SharedInitializationLocalSplitter.java @@ -149,6 +149,10 @@ protected void internalTransform(Body body, String phaseName, Map clusters = clustersPerLocal.get(lcl); if (clusters.size() <= 1) { - // Not interesting - continue; + //Do we have any non-cluster writes? + if (clusters.iterator().next().constantInitializers.containsAll(defs.getDefsOf(lcl))) { + // Not interesting + continue; + } } for (Cluster cluster : clusters) { // we have an overlap, we need to split.