/** * Collect all the if statements comparing two locals with an Eq or Ne * expression * * @param body * the body to analyze */ private Set<IfStmt> getNullIfCandidates(Body body) { Set<IfStmt> candidates = new HashSet<IfStmt>(); Iterator<Unit> i = body.getUnits().iterator(); while (i.hasNext()) { Unit u = i.next(); if (u instanceof IfStmt) { ConditionExpr expr = (ConditionExpr) ((IfStmt) u).getCondition(); boolean isTargetIf = false; if (((expr instanceof EqExpr) || (expr instanceof NeExpr))) { if (expr.getOp1() instanceof Local && expr.getOp2() instanceof Local) { isTargetIf = true; } } if (isTargetIf) { candidates.add((IfStmt) u); Debug.printDbg("[add if candidate: ", u); } } } return candidates; }
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); int elim=0; // -1 => condition is false, 1 => condition is true 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); }
/** * Examine expr if it is a comparison with 0. * * @param expr * the ConditionExpr to examine */ protected boolean isZeroComparison(ConditionExpr expr) { if (expr instanceof EqExpr || expr instanceof NeExpr) { if (expr.getOp2() instanceof IntConstant && ((IntConstant) expr.getOp2()).value == 0) return true; if (expr.getOp2() instanceof LongConstant && ((LongConstant) expr.getOp2()).value == 0) return true; } return false; }
private Value normalizeNegations(Value v) { if (v instanceof NegExpr) { return ((NegExpr)v).getOp(); } else if (v instanceof BinopExpr) { BinopExpr bo = (BinopExpr)v; if (bo instanceof NeExpr) { return new JEqExpr(bo.getOp1(), bo.getOp2()); } } return v; }
@Override public void visit(Value e) { if (e instanceof NeExpr) { NeExpr ne = (NeExpr) e; add(e, ne.getOp1(), ne.getOp2()); } }
@Override public void caseNeExpr(NeExpr v) { rightElement = RightElement.NOT; if (actualContext == StmtContext.ASSIGNRIGHT) { throw new NotSupportedStmtException("NeExpr"); } }
@Override public void caseNeExpr(NeExpr v) { throw new RuntimeException("todo"); }
public void caseNeExpr(NeExpr v) { printBinaryExpr(v); }
private void handleBinopExpr(BinopExpr be, Stmt stmt, Type tlhs) { Value opl = be.getOp1(), opr = be.getOp2(); Type tl = AugEvalFunction.eval_(this.tg, opl, stmt, this.jb), tr = AugEvalFunction.eval_(this.tg, opr, stmt, this.jb); if ( be instanceof AddExpr || be instanceof SubExpr || be instanceof MulExpr || be instanceof DivExpr || be instanceof RemExpr || be instanceof GeExpr || be instanceof GtExpr || be instanceof LeExpr || be instanceof LtExpr || be instanceof ShlExpr || be instanceof ShrExpr || be instanceof UshrExpr ) { if ( tlhs instanceof IntegerType ) { be.setOp1(this.uv.visit(opl, IntType.v(), stmt)); be.setOp2(this.uv.visit(opr, IntType.v(), stmt)); } } else if ( be instanceof CmpExpr || be instanceof CmpgExpr || be instanceof CmplExpr ) { // No checks in the original assigner } else if ( be instanceof AndExpr || be instanceof OrExpr || be instanceof XorExpr ) { be.setOp1(this.uv.visit(opl, tlhs, stmt)); be.setOp2(this.uv.visit(opr, tlhs, stmt)); } else if ( be instanceof EqExpr || be instanceof NeExpr ) { if ( tl instanceof BooleanType && tr instanceof BooleanType ) { } else if ( tl instanceof Integer1Type || tr instanceof Integer1Type ) { } else if ( tl instanceof IntegerType ) { be.setOp1(this.uv.visit(opl, IntType.v(), stmt)); be.setOp2(this.uv.visit(opr, IntType.v(), stmt)); } } }
@Override public void caseNeExpr(NeExpr ne) { stmtV.addInsn(buildComparingBinaryInsn("NE", ne.getOp1(), ne.getOp2()), origStmt); }
public void caseNeExpr(NeExpr expr) { caseBinopExpr(expr); }
@Override public void caseNeExpr(NeExpr arg0) { translateBinOp(arg0); }
/** * DOC * * @see soot.jimple.ExprSwitch#caseNeExpr(soot.jimple.NeExpr) */ @Override public void caseNeExpr(NeExpr v) { v.getOp1().apply(this); v.getOp2().apply(this); }
@Override public void caseNeExpr(NeExpr v) { throwInvalidWriteException(v); }
@Override public void caseNeExpr(NeExpr v) { handleBinaryExpr(v.getOp1(), v.getOp2()); }
/** * The method should update the <em>security level</em> of a {@link NeExpr}, * but it is not possible to update the level of an expression. * * @param v * The expression for which the <em>security level</em> should be * updated. * @see soot.jimple.ExprSwitch#caseNeExpr(soot.jimple.NeExpr) * @throws InvalidSwitchException * Always, because the update is not possible. */ @Override public void caseNeExpr(NeExpr v) { throw new SwitchException(getMsg("exception.analysis.switch.update_error", this.getClass().getSimpleName(), v.getClass().getSimpleName(), v.toString(), getSourceLine())); }
/** * Looks up the <em>security level</em> for the given binary expression and * stores the level in {@link SecurityLevelValueReadSwitch#level}. For a * {@link NeExpr} this is the strongest operand <em>security level</em> of * the given binary expression. * * @param v * The expression for which the <em>security level</em> should be * looked up. * @see soot.jimple.ExprSwitch#caseNeExpr(soot.jimple.NeExpr) * @see SecurityLevelValueReadSwitch#handleBinaryOperation(BinopExpr) */ @Override public void caseNeExpr(NeExpr v) { handleBinaryOperation(v); }