use of soot.NullType in project soot by Sable.
the class DeadAssignmentEliminator method internalTransform.
/**
* Eliminates dead code in a linear fashion. Complexity is linear
* with respect to the statements.
*
* Does not work on grimp code because of the check on the right hand
* side for side effects.
*/
@Override
protected void internalTransform(Body b, String phaseName, Map<String, String> options) {
boolean eliminateOnlyStackLocals = PhaseOptions.getBoolean(options, "only-stack-locals");
final Options soptions = Options.v();
if (soptions.verbose()) {
logger.debug("[" + b.getMethod().getName() + "] Eliminating dead code...");
}
if (soptions.time()) {
Timers.v().deadCodeTimer.start();
}
Chain<Unit> units = b.getUnits();
Deque<Unit> q = new ArrayDeque<Unit>(units.size());
// Make a first pass through the statements, noting
// the statements we must absolutely keep.
boolean isStatic = b.getMethod().isStatic();
boolean allEssential = true;
boolean checkInvoke = false;
Local thisLocal = null;
for (Iterator<Unit> it = units.iterator(); it.hasNext(); ) {
Unit s = it.next();
boolean isEssential = true;
if (s instanceof NopStmt) {
// Hack: do not remove nop if is is used for a Trap
// which is at the very end of the code.
boolean removeNop = it.hasNext();
if (!removeNop) {
removeNop = true;
for (Trap t : b.getTraps()) {
if (t.getEndUnit() == s) {
removeNop = false;
break;
}
}
}
if (removeNop) {
it.remove();
continue;
}
} else if (s instanceof AssignStmt) {
AssignStmt as = (AssignStmt) s;
Value lhs = as.getLeftOp();
Value rhs = as.getRightOp();
// Stmt is of the form a = a which is useless
if (lhs == rhs && lhs instanceof Local) {
it.remove();
continue;
}
if (lhs instanceof Local && (!eliminateOnlyStackLocals || ((Local) lhs).getName().startsWith("$") || lhs.getType() instanceof NullType)) {
isEssential = false;
if (!checkInvoke) {
checkInvoke = as.containsInvokeExpr();
}
if (rhs instanceof CastExpr) {
// CastExpr : can trigger ClassCastException, but null-casts never fail
CastExpr ce = (CastExpr) rhs;
Type t = ce.getCastType();
Value v = ce.getOp();
isEssential = !(v instanceof NullConstant && t instanceof RefType);
} else if (rhs instanceof InvokeExpr || rhs instanceof ArrayRef || rhs instanceof NewExpr || rhs instanceof NewArrayExpr || rhs instanceof NewMultiArrayExpr) {
// ArrayRef : can have side effects (like throwing a null pointer exception)
// InvokeExpr : can have side effects (like throwing a null pointer exception)
// NewArrayExpr : can throw exception
// NewMultiArrayExpr : can throw exception
// NewExpr : can trigger class initialization
isEssential = true;
} else if (rhs instanceof FieldRef) {
// Can trigger class initialization
isEssential = true;
if (rhs instanceof InstanceFieldRef) {
InstanceFieldRef ifr = (InstanceFieldRef) rhs;
if (!isStatic && thisLocal == null) {
thisLocal = b.getThisLocal();
}
// Any InstanceFieldRef may have side effects,
// unless the base is reading from 'this'
// in a non-static method
isEssential = (isStatic || thisLocal != ifr.getBase());
}
} else if (rhs instanceof DivExpr || rhs instanceof RemExpr) {
BinopExpr expr = (BinopExpr) rhs;
Type t1 = expr.getOp1().getType();
Type t2 = expr.getOp2().getType();
// Can trigger a division by zero
boolean t2Int = t2 instanceof IntType;
isEssential = t2Int || t1 instanceof IntType || t1 instanceof LongType || t2 instanceof LongType || t1 instanceof UnknownType || t2 instanceof UnknownType;
if (isEssential && t2Int) {
Value v = expr.getOp2();
if (v instanceof IntConstant) {
IntConstant i = (IntConstant) v;
isEssential = (i.value == 0);
} else
// could be 0, we don't know
isEssential = true;
}
if (isEssential && t2 instanceof LongType) {
Value v = expr.getOp2();
if (v instanceof LongConstant) {
LongConstant l = (LongConstant) v;
isEssential = (l.value == 0);
} else
// could be 0, we don't know
isEssential = true;
}
}
}
}
if (isEssential) {
q.addFirst(s);
}
allEssential &= isEssential;
}
if (checkInvoke || !allEssential) {
// Add all the statements which are used to compute values
// for the essential statements, recursively
final LocalDefs localDefs = LocalDefs.Factory.newLocalDefs(b);
if (!allEssential) {
Set<Unit> essential = new HashSet<Unit>(b.getUnits().size());
while (!q.isEmpty()) {
Unit s = q.removeFirst();
if (essential.add(s)) {
for (ValueBox box : s.getUseBoxes()) {
Value v = box.getValue();
if (v instanceof Local) {
Local l = (Local) v;
List<Unit> defs = localDefs.getDefsOfAt(l, s);
if (defs != null)
q.addAll(defs);
}
}
}
}
// Remove the dead statements
units.retainAll(essential);
}
if (checkInvoke) {
final LocalUses localUses = LocalUses.Factory.newLocalUses(b, localDefs);
// Eliminate dead assignments from invokes such as x = f(), where
// x is no longer used
List<AssignStmt> postProcess = new ArrayList<AssignStmt>();
for (Unit u : units) {
if (u instanceof AssignStmt) {
AssignStmt s = (AssignStmt) u;
if (s.containsInvokeExpr()) {
// Just find one use of l which is essential
boolean deadAssignment = true;
for (UnitValueBoxPair pair : localUses.getUsesOf(s)) {
if (units.contains(pair.unit)) {
deadAssignment = false;
break;
}
}
if (deadAssignment) {
postProcess.add(s);
}
}
}
}
final Jimple jimple = Jimple.v();
for (AssignStmt s : postProcess) {
// Transform it into a simple invoke.
Stmt newInvoke = jimple.newInvokeStmt(s.getInvokeExpr());
newInvoke.addAllTagsOf(s);
units.swapWith(s, newInvoke);
// If we have a callgraph, we need to fix it
if (Scene.v().hasCallGraph())
Scene.v().getCallGraph().swapEdgesOutOf(s, newInvoke);
}
}
}
if (soptions.time()) {
Timers.v().deadCodeTimer.end();
}
}
use of soot.NullType in project soot by Sable.
the class OnFlyCallGraphBuilder method resolveInvoke.
private void resolveInvoke(Collection<InvokeCallSite> list) {
for (InvokeCallSite ics : list) {
Set<Type> s = reachingBaseTypes.get(ics.base());
if (s == null || s.isEmpty()) {
continue;
}
if (ics.reachingTypes() != null) {
assert ics.nullnessCode() != InvokeCallSite.MUST_BE_NULL;
resolveStaticTypes(s, ics);
continue;
}
boolean mustNotBeNull = ics.nullnessCode() == InvokeCallSite.MUST_NOT_BE_NULL;
boolean mustBeNull = ics.nullnessCode() == InvokeCallSite.MUST_BE_NULL;
// yet, then generate nullary methods
if (mustBeNull || (ics.nullnessCode() == InvokeCallSite.MAY_BE_NULL && (!invokeArgsToSize.containsKey(ics.argArray()) || !reachingArgTypes.containsKey(ics.argArray())))) {
for (Type bType : s) {
assert bType instanceof RefType;
SootClass baseClass = ((RefType) bType).getSootClass();
assert !baseClass.isInterface();
Iterator<SootMethod> mIt = getPublicNullaryMethodIterator(baseClass);
while (mIt.hasNext()) {
SootMethod sm = mIt.next();
cm.addVirtualEdge(ics.container(), ics.stmt(), sm, Kind.REFL_INVOKE, null);
}
}
} else {
/*
* In this branch, either the invoke arg must not be null, or may be null and we
* have size and type information. Invert the above condition: ~mustBeNull &&
* (~mayBeNull || (has-size && has-type)) => (~mustBeNull && ~mayBeNull) ||
* (~mustBeNull && has-size && has-type) => mustNotBeNull || (~mustBeNull &&
* has-types && has-size) => mustNotBeNull || (mayBeNull && has-types &&
* has-size)
*/
Set<Type> reachingTypes = reachingArgTypes.get(ics.argArray());
/*
* the path condition allows must-not-be null without type and size info. Do
* nothing in this case. THIS IS UNSOUND if default null values in an argument
* array are used.
*/
if (reachingTypes == null || !invokeArgsToSize.containsKey(ics.argArray())) {
assert ics.nullnessCode() == InvokeCallSite.MUST_NOT_BE_NULL : ics;
return;
}
assert reachingTypes != null && invokeArgsToSize.containsKey(ics.argArray());
BitSet methodSizes = invokeArgsToSize.get(ics.argArray());
for (Type bType : s) {
assert bType instanceof RefLikeType;
// we do not handle static methods or array reflection
if (bType instanceof NullType || bType instanceof ArrayType) {
continue;
} else {
SootClass baseClass = ((RefType) bType).getSootClass();
Iterator<SootMethod> mIt = getPublicMethodIterator(baseClass, reachingTypes, methodSizes, mustNotBeNull);
while (mIt.hasNext()) {
SootMethod sm = mIt.next();
cm.addVirtualEdge(ics.container(), ics.stmt(), sm, Kind.REFL_INVOKE, null);
}
}
}
}
}
}
use of soot.NullType in project soot by Sable.
the class CopyPropagator method internalTransform.
/**
* Cascaded copy propagator.
*
* If it encounters situations of the form: A: a = ...; B: ... x = a; C:...
* use (x); where a has only one definition, and x has only one definition
* (B), then it can propagate immediately without checking between B and C
* for redefinitions of a (namely) A because they cannot occur. In this case
* the propagator is global.
*
* Otherwise, if a has multiple definitions then it only checks for
* redefinitions of Propagates constants and copies in extended basic
* blocks.
*
* Does not propagate stack locals when the "only-regular-locals" option is
* true.
*/
protected void internalTransform(Body b, String phaseName, Map<String, String> opts) {
CPOptions options = new CPOptions(opts);
StmtBody stmtBody = (StmtBody) b;
int fastCopyPropagationCount = 0;
int slowCopyPropagationCount = 0;
if (Options.v().verbose())
logger.debug("[" + stmtBody.getMethod().getName() + "] Propagating copies...");
if (Options.v().time())
Timers.v().propagatorTimer.start();
Chain<Unit> units = stmtBody.getUnits();
Map<Local, Integer> localToDefCount = new HashMap<Local, Integer>();
// Count number of definitions for each local.
for (Unit u : units) {
Stmt s = (Stmt) u;
if (s instanceof DefinitionStmt && ((DefinitionStmt) s).getLeftOp() instanceof Local) {
Local l = (Local) ((DefinitionStmt) s).getLeftOp();
if (!localToDefCount.containsKey(l))
localToDefCount.put(l, new Integer(1));
else
localToDefCount.put(l, new Integer(localToDefCount.get(l).intValue() + 1));
}
}
if (throwAnalysis == null)
throwAnalysis = Scene.v().getDefaultThrowAnalysis();
if (forceOmitExceptingUnitEdges == false)
forceOmitExceptingUnitEdges = Options.v().omit_excepting_unit_edges();
// Go through the definitions, building the webs
UnitGraph graph = new ExceptionalUnitGraph(stmtBody, throwAnalysis, forceOmitExceptingUnitEdges);
LocalDefs localDefs = LocalDefs.Factory.newLocalDefs(graph);
// Perform a local propagation pass.
{
Iterator<Unit> stmtIt = (new PseudoTopologicalOrderer<Unit>()).newList(graph, false).iterator();
while (stmtIt.hasNext()) {
Stmt stmt = (Stmt) stmtIt.next();
for (ValueBox useBox : stmt.getUseBoxes()) {
if (useBox.getValue() instanceof Local) {
Local l = (Local) useBox.getValue();
// null due to typing, we always inline that constant.
if (!(l.getType() instanceof NullType)) {
if (options.only_regular_locals() && l.getName().startsWith("$"))
continue;
if (options.only_stack_locals() && !l.getName().startsWith("$"))
continue;
}
List<Unit> defsOfUse = localDefs.getDefsOfAt(l, stmt);
// We can propagate the definition if we either only
// have
// one definition or all definitions are side-effect
// free
// and equal. For starters, we only support constants in
// the case of multiple definitions.
boolean propagateDef = defsOfUse.size() == 1;
if (!propagateDef && defsOfUse.size() > 0) {
boolean agrees = true;
Constant constVal = null;
for (Unit defUnit : defsOfUse) {
boolean defAgrees = false;
if (defUnit instanceof AssignStmt) {
AssignStmt assign = (AssignStmt) defUnit;
if (assign.getRightOp() instanceof Constant) {
if (constVal == null) {
constVal = (Constant) assign.getRightOp();
defAgrees = true;
} else if (constVal.equals(assign.getRightOp()))
defAgrees = true;
}
}
agrees &= defAgrees;
}
propagateDef = agrees;
}
if (propagateDef) {
DefinitionStmt def = (DefinitionStmt) defsOfUse.get(0);
if (def.getRightOp() instanceof Constant) {
if (useBox.canContainValue(def.getRightOp())) {
useBox.setValue(def.getRightOp());
}
} else if (def.getRightOp() instanceof CastExpr) {
CastExpr ce = (CastExpr) def.getRightOp();
if (ce.getCastType() instanceof RefLikeType) {
boolean isConstNull = ce.getOp() instanceof IntConstant && ((IntConstant) ce.getOp()).value == 0;
isConstNull |= ce.getOp() instanceof LongConstant && ((LongConstant) ce.getOp()).value == 0;
if (isConstNull) {
if (useBox.canContainValue(NullConstant.v())) {
useBox.setValue(NullConstant.v());
}
}
}
} else if (def.getRightOp() instanceof Local) {
Local m = (Local) def.getRightOp();
if (l != m) {
Integer defCount = localToDefCount.get(m);
if (defCount == null || defCount == 0)
throw new RuntimeException("Variable " + m + " used without definition!");
if (defCount == 1) {
useBox.setValue(m);
fastCopyPropagationCount++;
continue;
}
List<Unit> path = graph.getExtendedBasicBlockPathBetween(def, stmt);
if (path == null) {
// no path in the extended basic block
continue;
}
Iterator<Unit> pathIt = path.iterator();
// Skip first node
pathIt.next();
// Make sure that m is not redefined along
// path
{
boolean isRedefined = false;
while (pathIt.hasNext()) {
Stmt s = (Stmt) pathIt.next();
if (stmt == s) {
break;
}
if (s instanceof DefinitionStmt) {
if (((DefinitionStmt) s).getLeftOp() == m) {
isRedefined = true;
break;
}
}
}
if (isRedefined)
continue;
}
useBox.setValue(m);
slowCopyPropagationCount++;
}
}
}
}
}
}
}
if (Options.v().verbose())
logger.debug("[" + stmtBody.getMethod().getName() + "] Propagated: " + fastCopyPropagationCount + " fast copies " + slowCopyPropagationCount + " slow copies");
if (Options.v().time())
Timers.v().propagatorTimer.end();
}
use of soot.NullType in project soot by Sable.
the class LocalNameStandardizer method internalTransform.
@Override
protected void internalTransform(Body body, String phaseName, Map<String, String> options) {
boolean onlyStackName = PhaseOptions.getBoolean(options, "only-stack-locals");
boolean sortLocals = PhaseOptions.getBoolean(options, "sort-locals");
final BooleanType booleanType = BooleanType.v();
final ByteType byteType = ByteType.v();
final ShortType shortType = ShortType.v();
final CharType charType = CharType.v();
final IntType intType = IntType.v();
final LongType longType = LongType.v();
final DoubleType doubleType = DoubleType.v();
final FloatType floatType = FloatType.v();
final ErroneousType erroneousType = ErroneousType.v();
final UnknownType unknownType = UnknownType.v();
final StmtAddressType stmtAddressType = StmtAddressType.v();
final NullType nullType = NullType.v();
// Change the names to the standard forms now.
{
int objectCount = 0;
int intCount = 0;
int longCount = 0;
int floatCount = 0;
int doubleCount = 0;
int addressCount = 0;
int errorCount = 0;
int nullCount = 0;
/* The goal of this option is to ensure that local ordering remains
* consistent between different iterations of soot. This helps to ensure
* things like stable string representations of instructions and stable
* jimple representations of a methods body when soot is used to load
* the same code in different iterations.
*
* First sorts the locals alphabetically by the string representation of
* their type. Then if there are two locals with the same type, it uses
* the only other source of structurally stable information (i.e. the
* instructions themselves) to produce an ordering for the locals
* that remains consistent between different soot instances. It achieves
* this by determining the position of a local's first occurrence in the
* instruction's list of definition statements. This position is then used
* to sort the locals with the same type in an ascending order.
*
* The only times that this may not produce a consistent ordering for the
* locals between different soot instances is if a local is never defined in
* the instructions or if the instructions themselves are changed in some way
* that effects the ordering of the locals. In the first case, if a local is
* never defined, the other jimple body phases will remove this local as it is
* unused. As such, all we have to do is rerun this LocalNameStandardizer after
* all other jimple body phases to eliminate any ambiguity introduced by these
* phases and by the removed unused locals. In the second case, if the instructions
* themselves changed then the user would have had to intentionally told soot to
* modify the instructions of the code. Otherwise, the instructions would not have
* changed because we assume the instructions to always be structurally stable
* between different instances of soot. As such, in this instance, the user should
* not be expecting soot to produce the same output as the input and thus the
* ordering of the locals does not matter.
*/
if (sortLocals) {
Chain<Local> locals = body.getLocals();
final List<ValueBox> defs = body.getDefBoxes();
ArrayList<Local> sortedLocals = new ArrayList<Local>(locals);
Collections.sort(sortedLocals, new Comparator<Local>() {
private Map<Local, Integer> firstOccuranceCache = new HashMap<Local, Integer>();
@Override
public int compare(Local arg0, Local arg1) {
int ret = arg0.getType().toString().compareTo(arg1.getType().toString());
if (ret == 0) {
ret = Integer.compare(getFirstOccurance(arg0), getFirstOccurance(arg1));
}
return ret;
}
private int getFirstOccurance(Local l) {
Integer cur = firstOccuranceCache.get(l);
if (cur != null) {
return cur;
} else {
int count = 0;
int first = -1;
for (ValueBox vb : defs) {
Value v = vb.getValue();
if (v instanceof Local && v.equals(l)) {
first = count;
break;
}
count++;
}
firstOccuranceCache.put(l, first);
return first;
}
}
});
locals.clear();
locals.addAll(sortedLocals);
}
for (Local l : body.getLocals()) {
String prefix = "";
if (l.getName().startsWith("$"))
prefix = "$";
else {
if (onlyStackName)
continue;
}
final Type type = l.getType();
if (type.equals(booleanType))
l.setName(prefix + "z" + intCount++);
else if (type.equals(byteType))
l.setName(prefix + "b" + longCount++);
else if (type.equals(shortType))
l.setName(prefix + "s" + longCount++);
else if (type.equals(charType))
l.setName(prefix + "c" + longCount++);
else if (type.equals(intType))
l.setName(prefix + "i" + longCount++);
else if (type.equals(longType))
l.setName(prefix + "l" + longCount++);
else if (type.equals(doubleType))
l.setName(prefix + "d" + doubleCount++);
else if (type.equals(floatType))
l.setName(prefix + "f" + floatCount++);
else if (type.equals(stmtAddressType))
l.setName(prefix + "a" + addressCount++);
else if (type.equals(erroneousType) || type.equals(unknownType)) {
l.setName(prefix + "e" + errorCount++);
} else if (type.equals(nullType))
l.setName(prefix + "n" + nullCount++);
else
l.setName(prefix + "r" + objectCount++);
}
}
}
use of soot.NullType 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));
}
Aggregations