Search in sources :

Example 1 with ControlDependency

use of org.evosuite.graphs.cfg.ControlDependency 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 2 with ControlDependency

use of org.evosuite.graphs.cfg.ControlDependency in project evosuite by EvoSuite.

the class ImplicitElseTransformer method transformVarInsnNode.

/* (non-Javadoc)
	 * @see org.evosuite.instrumentation.MethodNodeTransformer#transformVarInsnNode(org.objectweb.asm.tree.MethodNode, org.objectweb.asm.tree.VarInsnNode)
	 */
@Override
protected AbstractInsnNode transformVarInsnNode(MethodNode mn, VarInsnNode varNode) {
    if (varNode.getOpcode() == Opcodes.ISTORE && this.booleanTestabilityTransformation.isBooleanVariable(varNode.var, mn)) {
        // Check if ICONST_0 or ICONST_1 are on the stack
        ControlDependenceGraph cdg = GraphPool.getInstance(this.booleanTestabilityTransformation.classLoader).getCDG(this.booleanTestabilityTransformation.className.replace("/", "."), mn.name + mn.desc);
        int index = mn.instructions.indexOf(varNode);
        BytecodeInstruction insn = BytecodeInstructionPool.getInstance(this.booleanTestabilityTransformation.classLoader).getInstruction(this.booleanTestabilityTransformation.className.replace("/", "."), mn.name + mn.desc, index);
        // varNode);
        if (insn == null) {
            // TODO: Debug this on org.exolab.jms.net.uri.URI
            BooleanTestabilityTransformation.logger.info("WARNING: Instruction not found!");
            return varNode;
        }
        if (insn.getASMNode().getOpcode() != varNode.getOpcode()) {
            BooleanTestabilityTransformation.logger.info("Found wrong bytecode instruction at this index!");
            insn = BytecodeInstructionPool.getInstance(this.booleanTestabilityTransformation.classLoader).getInstruction(this.booleanTestabilityTransformation.className, mn.name + mn.desc, varNode);
            if (insn == null) {
                // TODO: Debug this on org.exolab.jms.net.uri.URI
                BooleanTestabilityTransformation.logger.info("WARNING: Instruction not found!");
                return varNode;
            }
        }
        Set<ControlDependency> dependencies = insn.getControlDependencies();
        BooleanTestabilityTransformation.logger.info("Found flag assignment: " + insn + ", checking " + dependencies.size() + " control dependencies");
        for (ControlDependency dep : dependencies) {
            if (!addedNodes.contains(dep))
                handleDependency(dep, cdg, mn, varNode, insn);
        }
    // Only do completion if there's only one dependency
    // Not sure how other cases would look like
    /*
							//if (dependencies.size() > 1)
							//	return varNode;
							//else
							if (dependencies.isEmpty())
								return varNode;

							ControlDependency dep = dependencies.iterator().next();
							if (!addedNodes.contains(dep))
								handleDependency(dep, cdg, mn, varNode, insn);
								*/
    }
    return varNode;
}
Also used : ControlDependenceGraph(org.evosuite.graphs.cdg.ControlDependenceGraph) BytecodeInstruction(org.evosuite.graphs.cfg.BytecodeInstruction) ControlDependency(org.evosuite.graphs.cfg.ControlDependency)

Example 3 with ControlDependency

use of org.evosuite.graphs.cfg.ControlDependency in project evosuite by EvoSuite.

the class ImplicitElseTransformer method transformFieldInsnNode.

/* (non-Javadoc)
	 * @see org.evosuite.instrumentation.MethodNodeTransformer#transformFieldInsnNode(org.objectweb.asm.tree.MethodNode, org.objectweb.asm.tree.FieldInsnNode)
	 */
@SuppressWarnings("unchecked")
@Override
protected AbstractInsnNode transformFieldInsnNode(MethodNode mn, FieldInsnNode fieldNode) {
    if ((fieldNode.getOpcode() == Opcodes.PUTFIELD || fieldNode.getOpcode() == Opcodes.PUTSTATIC) && DescriptorMapping.getInstance().isTransformedOrBooleanField(fieldNode.owner, fieldNode.name, fieldNode.desc)) {
        if (addedInsns.contains(fieldNode))
            return fieldNode;
        // whether we need to pop one or two words
        if (fieldNode.getOpcode() == Opcodes.PUTFIELD) {
            AbstractInsnNode previous = fieldNode.getPrevious();
            while (previous instanceof LineNumberNode || previous instanceof FrameNode || previous.getOpcode() == Opcodes.ICONST_0 || previous.getOpcode() == Opcodes.ICONST_1) previous = previous.getPrevious();
            if (previous.getOpcode() != Opcodes.ALOAD) {
                BooleanTestabilityTransformation.logger.info("Can't handle case of " + previous);
                return fieldNode;
            }
            VarInsnNode varNode = (VarInsnNode) previous;
            if (varNode.var != 0) {
                BooleanTestabilityTransformation.logger.info("Can't handle case of " + previous);
                return fieldNode;
            }
        }
        BooleanTestabilityTransformation.logger.info("Handling PUTFIELD case!");
        // Check if ICONST_0 or ICONST_1 are on the stack
        ControlDependenceGraph cdg = GraphPool.getInstance(this.booleanTestabilityTransformation.classLoader).getCDG(this.booleanTestabilityTransformation.className.replace("/", "."), mn.name + mn.desc);
        int index = mn.instructions.indexOf(fieldNode);
        BooleanTestabilityTransformation.logger.info("Getting bytecode instruction for " + fieldNode.name + "/" + ((FieldInsnNode) mn.instructions.get(index)).name);
        InsnList nodes = mn.instructions;
        ListIterator<AbstractInsnNode> it = nodes.iterator();
        while (it.hasNext()) {
            BytecodeInstruction in = new BytecodeInstruction(this.booleanTestabilityTransformation.classLoader, this.booleanTestabilityTransformation.className, mn.name, 0, 0, it.next());
            BooleanTestabilityTransformation.logger.info(in.toString());
        }
        BytecodeInstruction insn = BytecodeInstructionPool.getInstance(this.booleanTestabilityTransformation.classLoader).getInstruction(this.booleanTestabilityTransformation.className.replace("/", "."), mn.name + mn.desc, index);
        if (insn == null)
            insn = BytecodeInstructionPool.getInstance(this.booleanTestabilityTransformation.classLoader).getInstruction(this.booleanTestabilityTransformation.className.replace("/", "."), mn.name + mn.desc, fieldNode);
        // varNode);
        if (insn == null) {
            // TODO: Find out why
            BooleanTestabilityTransformation.logger.info("ERROR: Could not find node");
            return fieldNode;
        }
        if (insn.getASMNode().getOpcode() != fieldNode.getOpcode()) {
            BooleanTestabilityTransformation.logger.info("Found wrong bytecode instruction at this index!");
            BytecodeInstructionPool.getInstance(this.booleanTestabilityTransformation.classLoader).getInstruction(this.booleanTestabilityTransformation.className, mn.name + mn.desc, fieldNode);
        }
        if (insn.getBasicBlock() == null) {
            BooleanTestabilityTransformation.logger.info("ERROR: Problematic node found");
            return fieldNode;
        }
        Set<ControlDependency> dependencies = insn.getControlDependencies();
        BooleanTestabilityTransformation.logger.info("Found flag assignment: " + insn + ", checking " + dependencies.size() + " control dependencies");
        for (ControlDependency dep : dependencies) {
            if (!addedNodes.contains(dep))
                handleDependency(dep, cdg, mn, fieldNode, insn);
        }
    }
    return fieldNode;
}
Also used : FrameNode(org.objectweb.asm.tree.FrameNode) ControlDependenceGraph(org.evosuite.graphs.cdg.ControlDependenceGraph) FieldInsnNode(org.objectweb.asm.tree.FieldInsnNode) LineNumberNode(org.objectweb.asm.tree.LineNumberNode) BytecodeInstruction(org.evosuite.graphs.cfg.BytecodeInstruction) AbstractInsnNode(org.objectweb.asm.tree.AbstractInsnNode) VarInsnNode(org.objectweb.asm.tree.VarInsnNode) InsnList(org.objectweb.asm.tree.InsnList) ControlDependency(org.evosuite.graphs.cfg.ControlDependency)

Example 4 with ControlDependency

use of org.evosuite.graphs.cfg.ControlDependency 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)

Example 5 with ControlDependency

use of org.evosuite.graphs.cfg.ControlDependency in project evosuite by EvoSuite.

the class ImplicitElseTransformer method handleDependency.

private void handleDependency(ControlDependency dependency, ControlDependenceGraph cdg, MethodNode mn, FieldInsnNode 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.PUTFIELD || instruction.getASMNode().getOpcode() == Opcodes.PUTSTATIC) {
                FieldInsnNode otherFieldNode = (FieldInsnNode) instruction.getASMNode();
                FieldInsnNode thisFieldNode = varNode;
                if (otherFieldNode.owner.equals(thisFieldNode.owner) && otherFieldNode.name.equals(thisFieldNode.name)) {
                    hasAssignment = true;
                    break;
                }
            }
        }
        if (hasAssignment) {
            break;
        }
    }
    if (!hasAssignment) {
        if (dependency.getBranch().getInstruction().isSwitch()) {
            BooleanTestabilityTransformation.logger.warn("Don't know how to handle Switches yet");
            return;
        }
        TransformationStatistics.transformedImplicitElse();
        JumpInsnNode jumpNode = (JumpInsnNode) dependency.getBranch().getInstruction().getASMNode();
        FieldInsnNode newLoad = new FieldInsnNode(varNode.getOpcode() == Opcodes.PUTSTATIC ? Opcodes.GETSTATIC : Opcodes.GETFIELD, varNode.owner, varNode.name, varNode.desc);
        FieldInsnNode newStore = new FieldInsnNode(varNode.getOpcode(), varNode.owner, varNode.name, varNode.desc);
        AbstractInsnNode newOwnerLoad1 = null;
        AbstractInsnNode newOwnerLoad2 = null;
        if (varNode.getOpcode() == Opcodes.PUTFIELD) {
            // Need to copy the bloody owner
            // Check for VarInsn
            // if (varNode.getPrevious().getOpcode() == Opcodes.ALOAD) {
            newOwnerLoad1 = new VarInsnNode(Opcodes.ALOAD, 0);
            newOwnerLoad2 = new VarInsnNode(Opcodes.ALOAD, 0);
        /*
				} else {
				// Else use helper function
				// Insert DUP and
				logger.info("Wargh");
				System.exit(0);
				fieldOwnerId++;
				InsnNode dupNode = new InsnNode(Opcodes.DUP);
				mn.instructions.insertBefore(varNode, new LdcInsnNode(
				        fieldOwnerId));
				mn.instructions.insertBefore(varNode, dupNode);
				registerInstruction(mn, varNode, dupNode);
				MethodInsnNode storeOwner = new MethodInsnNode(
				        Opcodes.INVOKESTATIC,
				        "org/evosuite/instrumentation/BooleanHelper",
				        "setFieldOwner", "(ILjava/lang/Object;)V");
				mn.instructions.insertBefore(varNode, storeOwner);
				registerInstruction(mn, varNode, storeOwner);
				newOwnerLoad1 = new MethodInsnNode(Opcodes.INVOKESTATIC,
				        "org/evosuite/instrumentation/BooleanHelper",
				        "getFieldOwner", "(I)Ljava/lang/Object;");
				newOwnerLoad2 = new MethodInsnNode(Opcodes.INVOKESTATIC,
				        "org/evosuite/instrumentation/BooleanHelper",
				        "getFieldOwner", "(I)Ljava/lang/Object;");
				}
				*/
        }
        if (dependency.getBranchExpressionValue()) {
            BooleanTestabilityTransformation.logger.info("Inserting after if");
            // Insert directly after if
            mn.instructions.insert(jumpNode, newStore);
            mn.instructions.insert(jumpNode, newLoad);
            if (newOwnerLoad1 != null) {
                mn.instructions.insert(jumpNode, newOwnerLoad1);
                registerInstruction(mn, varNode, newOwnerLoad1);
            }
            if (newOwnerLoad2 != null) {
                mn.instructions.insert(jumpNode, newOwnerLoad2);
                registerInstruction(mn, varNode, newOwnerLoad2);
            }
            registerInstruction(mn, varNode, newStore);
            registerInstruction(mn, varNode, newLoad);
        } else {
            BooleanTestabilityTransformation.logger.info("Inserting as jump target");
            // Insert as jump target
            LabelNode target = jumpNode.label;
            LabelNode newTarget = new LabelNode(new Label());
            registerInstruction(mn, target, newStore);
            registerInstruction(mn, target, newLoad);
            InsnList assignment = new InsnList();
            assignment.add(new JumpInsnNode(Opcodes.GOTO, target));
            assignment.add(newTarget);
            if (newOwnerLoad1 != null) {
                assignment.add(newOwnerLoad1);
                registerInstruction(mn, target, newOwnerLoad1);
            }
            if (newOwnerLoad2 != null) {
                assignment.add(newOwnerLoad2);
                registerInstruction(mn, target, newOwnerLoad2);
            }
            assignment.add(newLoad);
            assignment.add(newStore);
            jumpNode.label = newTarget;
            mn.instructions.insertBefore(target, assignment);
        }
        addedInsns.add(newStore);
        addedInsns.add(newLoad);
    }
}
Also used : LabelNode(org.objectweb.asm.tree.LabelNode) BasicBlock(org.evosuite.graphs.cfg.BasicBlock) Label(org.objectweb.asm.Label) FieldInsnNode(org.objectweb.asm.tree.FieldInsnNode) BytecodeInstruction(org.evosuite.graphs.cfg.BytecodeInstruction) AbstractInsnNode(org.objectweb.asm.tree.AbstractInsnNode) InsnList(org.objectweb.asm.tree.InsnList) JumpInsnNode(org.objectweb.asm.tree.JumpInsnNode) VarInsnNode(org.objectweb.asm.tree.VarInsnNode) ControlDependency(org.evosuite.graphs.cfg.ControlDependency)

Aggregations

ControlDependency (org.evosuite.graphs.cfg.ControlDependency)10 BytecodeInstruction (org.evosuite.graphs.cfg.BytecodeInstruction)5 BasicBlock (org.evosuite.graphs.cfg.BasicBlock)3 InsnList (org.objectweb.asm.tree.InsnList)3 VarInsnNode (org.objectweb.asm.tree.VarInsnNode)3 LinkedHashSet (java.util.LinkedHashSet)2 ControlDependenceGraph (org.evosuite.graphs.cdg.ControlDependenceGraph)2 Label (org.objectweb.asm.Label)2 AbstractInsnNode (org.objectweb.asm.tree.AbstractInsnNode)2 FieldInsnNode (org.objectweb.asm.tree.FieldInsnNode)2 JumpInsnNode (org.objectweb.asm.tree.JumpInsnNode)2 LabelNode (org.objectweb.asm.tree.LabelNode)2 HashSet (java.util.HashSet)1 ControlFlowDistance (org.evosuite.coverage.ControlFlowDistance)1 BranchCoverageGoal (org.evosuite.coverage.branch.BranchCoverageGoal)1 BranchCoverageTestFitness (org.evosuite.coverage.branch.BranchCoverageTestFitness)1 ControlFlowEdge (org.evosuite.graphs.cfg.ControlFlowEdge)1 TestFitnessFunction (org.evosuite.testcase.TestFitnessFunction)1 FrameNode (org.objectweb.asm.tree.FrameNode)1 LineNumberNode (org.objectweb.asm.tree.LineNumberNode)1