Search in sources :

Example 1 with BasicBlock

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;
}
Also used : LinkedHashSet(java.util.LinkedHashSet) ControlFlowEdge(org.evosuite.graphs.cfg.ControlFlowEdge) Branch(org.evosuite.coverage.branch.Branch) BasicBlock(org.evosuite.graphs.cfg.BasicBlock)

Example 2 with BasicBlock

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());
        }
    }
}
Also used : ActualControlFlowGraph(org.evosuite.graphs.cfg.ActualControlFlowGraph) HashSet(java.util.HashSet) Set(java.util.Set) LinkedHashSet(java.util.LinkedHashSet) ControlFlowEdge(org.evosuite.graphs.cfg.ControlFlowEdge) BasicBlock(org.evosuite.graphs.cfg.BasicBlock)

Example 3 with BasicBlock

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;
}
Also used : ControlFlowEdge(org.evosuite.graphs.cfg.ControlFlowEdge) BasicBlock(org.evosuite.graphs.cfg.BasicBlock)

Example 4 with BasicBlock

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;
}
Also used : LinkedHashSet(java.util.LinkedHashSet) ControlFlowEdge(org.evosuite.graphs.cfg.ControlFlowEdge) BasicBlock(org.evosuite.graphs.cfg.BasicBlock) ControlDependency(org.evosuite.graphs.cfg.ControlDependency)

Example 5 with BasicBlock

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);
            }
        }
    }
}
Also used : LabelNode(org.objectweb.asm.tree.LabelNode) BasicBlock(org.evosuite.graphs.cfg.BasicBlock) Label(org.objectweb.asm.Label) JumpInsnNode(org.objectweb.asm.tree.JumpInsnNode) BytecodeInstruction(org.evosuite.graphs.cfg.BytecodeInstruction) VarInsnNode(org.objectweb.asm.tree.VarInsnNode) InsnList(org.objectweb.asm.tree.InsnList) ControlDependency(org.evosuite.graphs.cfg.ControlDependency)

Aggregations

BasicBlock (org.evosuite.graphs.cfg.BasicBlock)7 ControlFlowEdge (org.evosuite.graphs.cfg.ControlFlowEdge)4 LinkedHashSet (java.util.LinkedHashSet)3 ControlDependency (org.evosuite.graphs.cfg.ControlDependency)3 HashSet (java.util.HashSet)2 BytecodeInstruction (org.evosuite.graphs.cfg.BytecodeInstruction)2 Label (org.objectweb.asm.Label)2 InsnList (org.objectweb.asm.tree.InsnList)2 JumpInsnNode (org.objectweb.asm.tree.JumpInsnNode)2 LabelNode (org.objectweb.asm.tree.LabelNode)2 VarInsnNode (org.objectweb.asm.tree.VarInsnNode)2 Set (java.util.Set)1 Branch (org.evosuite.coverage.branch.Branch)1 ActualControlFlowGraph (org.evosuite.graphs.cfg.ActualControlFlowGraph)1 AbstractInsnNode (org.objectweb.asm.tree.AbstractInsnNode)1 FieldInsnNode (org.objectweb.asm.tree.FieldInsnNode)1