use of soot.dava.internal.AST.ASTUnaryCondition in project soot by Sable.
the class EliminateConditions method eliminate.
public Boolean eliminate(ASTNode node) {
ASTCondition cond = null;
if (node instanceof ASTControlFlowNode)
cond = ((ASTControlFlowNode) node).get_Condition();
else
return null;
if (cond == null || !(cond instanceof ASTUnaryCondition))
return null;
ASTUnaryCondition unary = (ASTUnaryCondition) cond;
Value unaryValue = unary.getValue();
boolean notted = false;
if (unaryValue instanceof DNotExpr) {
notted = true;
unaryValue = ((DNotExpr) unaryValue).getOp();
}
Boolean isBoolean = isBooleanConstant(unaryValue);
if (isBoolean == null) {
// not a constant
return null;
}
boolean trueOrFalse = isBoolean.booleanValue();
if (notted) {
// since it is notted we reverse the booleans
trueOrFalse = !trueOrFalse;
}
AST.apply(finder);
Object temp = finder.getParentOf(node);
if (temp == null)
return null;
ASTNode parent = (ASTNode) temp;
List<Object> subBodies = parent.get_SubBodies();
Iterator<Object> it = subBodies.iterator();
int index = -1;
while (it.hasNext()) {
bodyContainingNode = (List<Object>) it.next();
index = bodyContainingNode.indexOf(node);
if (index < 0) {
bodyContainingNode = null;
} else {
// bound the body containing Node
return new Boolean(trueOrFalse);
}
}
return null;
}
use of soot.dava.internal.AST.ASTUnaryCondition in project soot by Sable.
the class CPApplication method changedCondition.
/*
* Given a unary/binary or aggregated condition this method is used to find
* all the useBoxes or locals or fieldref in the case of unary conditions
* and then the set is checked for appropriate substitutions
*/
public ASTCondition changedCondition(ASTCondition cond, CPFlowSet set) {
if (cond instanceof ASTAggregatedCondition) {
ASTCondition left = changedCondition(((ASTAggregatedCondition) cond).getLeftOp(), set);
ASTCondition right = changedCondition(((ASTAggregatedCondition) cond).getRightOp(), set);
((ASTAggregatedCondition) cond).setLeftOp(left);
((ASTAggregatedCondition) cond).setRightOp(right);
// System.out.println("New condition is: "+cond);
return cond;
} else if (cond instanceof ASTUnaryCondition) {
Value val = ((ASTUnaryCondition) cond).getValue();
if (val instanceof Local) {
Object value = set.contains(className, ((Local) val).toString());
if (value != null) {
// System.out.println("if Condition Local "+((Local)val)+"is present in before set with value"+value);
// create constant value for the value and replace this
// local use with the constant value use
Value newValue = CPHelper.createConstant(value);
if (newValue != null) {
// System.out.println("Substituted the local use with the constant value"+newValue);
((ASTUnaryCondition) cond).setValue(newValue);
} else {
// System.out.println("FAILED TO Substitute the local use with the constant value");
}
}
} else if (val instanceof FieldRef) {
FieldRef useField = (FieldRef) val;
SootField usedSootField = useField.getField();
Object value = set.contains(usedSootField.getDeclaringClass().getName(), usedSootField.getName().toString());
if (value != null) {
// System.out.println("if condition FieldRef "+usedSootField+"is present in before set with value"+value);
// create constant value for the value and replace this
// field use with the constant value use
Value newValue = CPHelper.createConstant(value);
if (newValue != null) {
// System.out.println("Substituted the constant field ref use with the constant value"+newValue);
((ASTUnaryCondition) cond).setValue(newValue);
} else {
// System.out.println("FAILED TO Substitute the constant field ref use with the constant value");
}
}
} else {
substituteUses(val.getUseBoxes(), set);
}
// System.out.println("New condition is: "+cond);
return cond;
} else if (cond instanceof ASTBinaryCondition) {
// get uses from binaryCondition
Value val = ((ASTBinaryCondition) cond).getConditionExpr();
substituteUses(val.getUseBoxes(), set);
// System.out.println("New condition is: "+cond);
return cond;
} else {
throw new RuntimeException("Method getUseList in ASTUsesAndDefs encountered unknown condition type");
}
}
use of soot.dava.internal.AST.ASTUnaryCondition in project soot by Sable.
the class CP method checkForValueHints.
/*
* The isElseBranch flag is true if the caller is the else branch of the
* ifelse statement. In that case we might be able to send something for the
* else branch
*/
public CPTuple checkForValueHints(ASTCondition cond, CPFlowSet input, boolean isElseBranch) {
if (cond instanceof ASTUnaryCondition) {
// check for lone boolean if(notDone)
ASTUnaryCondition unary = (ASTUnaryCondition) cond;
Value unaryValue = unary.getValue();
boolean NOTTED = false;
// Get the real value if this is a notted expression
if (unaryValue instanceof DNotExpr) {
unaryValue = ((DNotExpr) unaryValue).getOp();
NOTTED = true;
}
if (!(unaryValue instanceof Local)) {
// inset
return null;
}
// the unary value is a local add the value to the inset which woul
// dbe present in the if branch
CPVariable variable = new CPVariable((Local) unaryValue);
// false and vice verse
if (!isElseBranch) {
// we are in the if branch hence notted true would mean the
// variable is actually false here
Boolean boolVal = new Boolean(!NOTTED);
return new CPTuple(localClassName, variable, boolVal);
} else {
// in the else branch NOTTED true means the variable is true
Boolean boolVal = new Boolean(NOTTED);
return new CPTuple(localClassName, variable, boolVal);
}
} else if (cond instanceof ASTBinaryCondition) {
ASTBinaryCondition binary = (ASTBinaryCondition) cond;
ConditionExpr expr = binary.getConditionExpr();
Boolean equal = null;
String symbol = expr.getSymbol();
if (symbol.indexOf("==") > -1) {
// System.out.println("!!!!!!!!!1 FOUND == in binary comparison operaiton");
equal = new Boolean(true);
} else if (symbol.indexOf("!=") > -1) {
equal = new Boolean(false);
// System.out.println("!!!!!!!!!!!!!! FOUND != in binary comparison operaiton");
} else {
// System.out.println("symbol is"+symbol);
return null;
}
// we have a comparison the truth value of equal tells whether we
// are doing == or !=
Value a = expr.getOp1();
Value b = expr.getOp2();
// see if its possible to deduce a hint from these values
CPTuple tuple = createCPTupleIfPossible(a, b, input);
// if the tuple is not created
if (tuple == null)
return null;
// we have to make sure is that the == and != are taken into account
if (equal.booleanValue()) {
// branch a is in fact equal to b
if (!isElseBranch)
return tuple;
else
return null;
} else {
if (isElseBranch)
return tuple;
else
return null;
}
}
return null;
}
use of soot.dava.internal.AST.ASTUnaryCondition in project soot by Sable.
the class EliminateConditions method eliminateForTry.
public Boolean eliminateForTry(ASTNode node) {
ASTCondition cond = null;
if (node instanceof ASTControlFlowNode)
cond = ((ASTControlFlowNode) node).get_Condition();
else
return null;
if (cond == null || !(cond instanceof ASTUnaryCondition))
return null;
ASTUnaryCondition unary = (ASTUnaryCondition) cond;
Value unaryValue = unary.getValue();
boolean notted = false;
if (unaryValue instanceof DNotExpr) {
notted = true;
unaryValue = ((DNotExpr) unaryValue).getOp();
}
Boolean isBoolean = isBooleanConstant(unaryValue);
if (isBoolean == null) {
// not a constant
return null;
}
boolean trueOrFalse = isBoolean.booleanValue();
if (notted) {
// since it is notted we reverse the booleans
trueOrFalse = !trueOrFalse;
}
AST.apply(finder);
Object temp = finder.getParentOf(node);
if (temp == null)
return null;
if (!(temp instanceof ASTTryNode))
throw new RuntimeException("eliminateTry called when parent was not a try node");
ASTTryNode parent = (ASTTryNode) temp;
List<Object> tryBody = parent.get_TryBody();
int index = tryBody.indexOf(node);
if (index >= 0) {
// bound the body containing Node
bodyContainingNode = tryBody;
return new Boolean(trueOrFalse);
}
List<Object> catchList = parent.get_CatchList();
Iterator<Object> it = catchList.iterator();
while (it.hasNext()) {
ASTTryNode.container catchBody = (ASTTryNode.container) it.next();
List<Object> body = (List<Object>) catchBody.o;
index = body.indexOf(node);
if (index >= 0) {
// bound the body containing Node
bodyContainingNode = body;
return new Boolean(trueOrFalse);
}
}
return null;
}
use of soot.dava.internal.AST.ASTUnaryCondition in project soot by Sable.
the class SimplifyConditions method simplifyIfAtleastOneConstant.
/*
* When this method is invoked we are sure that there are no occurences of !true or !false since
* this is AFTER doing depth first of the children so the unaryCondition must have simplified the above
*
* Return Null if no change else return changed condition
*/
public ASTCondition simplifyIfAtleastOneConstant(ASTAggregatedCondition aggCond) {
ASTCondition left = aggCond.getLeftOp();
ASTCondition right = aggCond.getRightOp();
Boolean leftBool = null;
Boolean rightBool = null;
if (left instanceof ASTUnaryCondition)
leftBool = isBooleanConstant(((ASTUnaryCondition) left).getValue());
if (right instanceof ASTUnaryCondition)
rightBool = isBooleanConstant(((ASTUnaryCondition) right).getValue());
/*
* a && b NOCHANGE DONE
* b && a NOCHANGE DONE
*
* a || b NOCHANGE DONE
* b || a NOCHANGE DONE
*
*/
if (leftBool == null && rightBool == null) {
// meaning both are not constants
return null;
}
if (aggCond instanceof ASTAndCondition) {
if (leftBool != null && rightBool != null) {
// meaning both are constants
if (leftBool.booleanValue() && rightBool.booleanValue()) {
// both are true
return new ASTUnaryCondition(DIntConstant.v(1, BooleanType.v()));
} else {
// atleast one of the two is false
return new ASTUnaryCondition(DIntConstant.v(0, BooleanType.v()));
}
}
if (leftBool != null) {
// condition passed
if (leftBool.booleanValue()) {
// condition.......just return the right condition
return right;
} else {
// return a unary false
return new ASTUnaryCondition(DIntConstant.v(0, BooleanType.v()));
}
}
if (rightBool != null) {
// implicityly means that the leftBool is null
if (rightBool.booleanValue()) {
// rightBool is true so it all depends on left
return left;
} else {
// remove the leftBool since there might be side effects
return aggCond;
}
}
} else if (aggCond instanceof ASTOrCondition) {
/*
*
* true || false ---> true DONE
* true || true --> true DONE
* false || true --> true DONE
* false || false ---> false DONE
*
*
* true || b ----> true DONE
* false || b -----> b DONE
*
* b || true ---> b || true .... although we know the condition is true we have to evaluate b because of possible side effects DONE
* b || false ---> b DONE
*
*/
if (leftBool != null && rightBool != null) {
// meaning both are constants
if (!leftBool.booleanValue() && !rightBool.booleanValue()) {
// both are false
return new ASTUnaryCondition(DIntConstant.v(0, BooleanType.v()));
} else {
// atleast one of the two is true
return new ASTUnaryCondition(DIntConstant.v(1, BooleanType.v()));
}
}
if (leftBool != null) {
// condition passed
if (leftBool.booleanValue()) {
// left bool is true that means we will stop evaluation of condition, just return true
return new ASTUnaryCondition(DIntConstant.v(1, BooleanType.v()));
} else {
// left bool is false so we have to continue evaluating right
return right;
}
}
if (rightBool != null) {
// implicityly means that the leftBool is null
if (rightBool.booleanValue()) {
// rightBool is true but leftBool must be evaluated beforehand
return aggCond;
} else {
// rightBool is false so everything depends on left
return left;
}
}
} else
throw new RuntimeException("Found unknown aggregated condition");
return null;
}
Aggregations