use of org.evosuite.graphs.cfg.BasicBlock in project evosuite by EvoSuite.
the class ControlDependenceGraph method getAlternativeBlocks.
/**
* <p>getAlternativeBlocks</p>
*
* @param dependency a {@link org.evosuite.graphs.cfg.ControlDependency} object.
* @return a {@link java.util.Set} object.
*/
public Set<BasicBlock> getAlternativeBlocks(ControlDependency dependency) {
Set<BasicBlock> blocks = new LinkedHashSet<>();
Branch branch = dependency.getBranch();
BasicBlock block = branch.getInstruction().getBasicBlock();
for (ControlFlowEdge e : outgoingEdgesOf(block)) {
// TODO: Why can this be null?
if (e.getControlDependency() == null || e.getControlDependency().equals(dependency))
continue;
BasicBlock next = getEdgeTarget(e);
blocks.add(next);
getReachableBasicBlocks(blocks, next);
// blocks.addAll(getReachableBasicBlocks(next));
}
return blocks;
}
use of org.evosuite.graphs.cfg.BasicBlock in project evosuite by EvoSuite.
the class ControlDependenceGraph method computeControlDependence.
private void computeControlDependence() {
ActualControlFlowGraph rcfg = cfg.computeReverseCFG();
DominatorTree<BasicBlock> dt = new DominatorTree<BasicBlock>(rcfg);
for (BasicBlock b : rcfg.vertexSet()) if (!b.isExitBlock()) {
logger.debug("DFs for: " + b.getName());
for (BasicBlock cd : dt.getDominatingFrontiers(b)) {
ControlFlowEdge orig = cfg.getEdge(cd, b);
if (!cd.isEntryBlock() && orig == null) {
// in for loops for example it can happen that cd and b
// were not directly adjacent to each other in the CFG
// but rather there were some intermediate nodes between
// them and the needed information is inside one of the
// edges
// from cd to the first intermediate node. more
// precisely cd is expected to be a branch and to have 2
// outgoing edges, one for evaluating to true (jumping)
// and one for false. one of them can be followed and b
// will eventually be reached, the other one can not be
// followed in that way. TODO TRY!
logger.debug("cd: " + cd.toString());
logger.debug("b: " + b.toString());
// TODO this is just for now! unsafe and probably not
// even correct!
Set<ControlFlowEdge> candidates = cfg.outgoingEdgesOf(cd);
if (candidates.size() < 2)
throw new IllegalStateException("unexpected");
boolean leadToB = false;
boolean skip = false;
for (ControlFlowEdge e : candidates) {
if (!e.hasControlDependency()) {
skip = true;
break;
}
if (cfg.leadsToNode(e, b)) {
if (leadToB)
orig = null;
// throw new
// IllegalStateException("unexpected");
leadToB = true;
orig = e;
}
}
if (skip)
continue;
if (!leadToB)
throw new IllegalStateException("unexpected");
}
if (orig == null)
logger.debug("orig still null!");
if (!addEdge(cd, b, new ControlFlowEdge(orig)))
throw new IllegalStateException("internal error while adding CD edge");
logger.debug(" " + cd.getName());
}
}
}
use of org.evosuite.graphs.cfg.BasicBlock in project evosuite by EvoSuite.
the class ControlDependenceGraph method getReachableBasicBlocks.
private void getReachableBasicBlocks(Set<BasicBlock> blocks, BasicBlock start) {
for (ControlFlowEdge e : outgoingEdgesOf(start)) {
BasicBlock next = getEdgeTarget(e);
if (!blocks.contains(next)) {
blocks.add(next);
getReachableBasicBlocks(blocks, next);
// blocks.addAll(getReachableBasicBlocks(next));
}
}
// return blocks;
}
use of org.evosuite.graphs.cfg.BasicBlock in project evosuite by EvoSuite.
the class ControlDependenceGraph method retrieveControlDependencies.
private Set<ControlDependency> retrieveControlDependencies(BasicBlock insBlock, Set<ControlFlowEdge> handled) {
Set<ControlDependency> r = new LinkedHashSet<>();
for (ControlFlowEdge e : incomingEdgesOf(insBlock)) {
if (handled.contains(e))
continue;
handled.add(e);
ControlDependency cd = e.getControlDependency();
if (cd != null)
r.add(cd);
else {
BasicBlock in = getEdgeSource(e);
if (!in.equals(insBlock))
r.addAll(retrieveControlDependencies(in, handled));
}
}
return r;
}
use of org.evosuite.graphs.cfg.BasicBlock in project evosuite by EvoSuite.
the class ImplicitElseTransformer method handleDependency.
private void handleDependency(ControlDependency dependency, ControlDependenceGraph cdg, MethodNode mn, VarInsnNode varNode, BytecodeInstruction parentLevel) {
if (addedNodes.contains(dependency))
return;
// Get the basic blocks reachable if the dependency would evaluate different
Set<BasicBlock> blocks = cdg.getAlternativeBlocks(dependency);
addedNodes.add(dependency);
Set<ControlDependency> dependencies = dependency.getBranch().getInstruction().getControlDependencies();
// ControlDependency dep = dependencies.iterator().next();
for (ControlDependency dep : dependencies) {
if (!addedNodes.contains(dep) && dep != dependency)
handleDependency(dep, cdg, mn, varNode, dependency.getBranch().getInstruction());
}
// TODO: Need to check that there is an assignment in every alternative path through CDG
boolean hasAssignment = false;
for (BasicBlock block : blocks) {
// If this block also assigns a value to the same variable
for (BytecodeInstruction instruction : block) {
if (instruction.getASMNode().getOpcode() == Opcodes.ISTORE) {
VarInsnNode otherVarNode = (VarInsnNode) instruction.getASMNode();
VarInsnNode thisVarNode = varNode;
if (otherVarNode.var == thisVarNode.var) {
hasAssignment = true;
break;
}
}
}
if (hasAssignment) {
break;
}
}
if (!hasAssignment) {
TransformationStatistics.transformedImplicitElse();
if (dependency.getBranch().getInstruction().isSwitch()) {
BooleanTestabilityTransformation.logger.warn("Don't know how to handle Switches yet");
return;
}
JumpInsnNode jumpNode = (JumpInsnNode) dependency.getBranch().getInstruction().getASMNode();
VarInsnNode newStore = new VarInsnNode(Opcodes.ISTORE, varNode.var);
VarInsnNode newLoad = new VarInsnNode(Opcodes.ILOAD, varNode.var);
if (dependency.getBranchExpressionValue()) {
BooleanTestabilityTransformation.logger.info("Inserting else branch directly after if");
// Insert directly after if
if (isDefinedBefore(mn, varNode, jumpNode)) {
mn.instructions.insert(jumpNode, newStore);
mn.instructions.insert(jumpNode, newLoad);
registerInstruction(mn, varNode, newStore);
registerInstruction(mn, varNode, newLoad);
}
} else {
BooleanTestabilityTransformation.logger.info("Inserting else branch as jump target");
// Insert as jump target
if (isDefinedBefore(mn, varNode, jumpNode)) {
LabelNode target = jumpNode.label;
LabelNode newTarget = new LabelNode(new Label());
// jumpNode or target?
registerInstruction(mn, jumpNode.getNext(), newStore);
registerInstruction(mn, jumpNode.getNext(), newLoad);
InsnList assignment = new InsnList();
assignment.add(new JumpInsnNode(Opcodes.GOTO, target));
assignment.add(newTarget);
assignment.add(newLoad);
assignment.add(newStore);
jumpNode.label = newTarget;
mn.instructions.insertBefore(target, assignment);
}
}
}
}
Aggregations