@Override /** comparison based on the child element */ public int compareTo(Edge pO) { return Integer.compare(this.getChildState().getStateId(), pO.getChildState().getStateId()); }
private Collection<Edge> handleEdge( Edge nextEdge, Map<Integer, MergeNode> mergeNodes, Set<ARGState> elementsOnPath, EdgeVisitor callback) { ARGState childElement = nextEdge.getChildState(); CFAEdge edge = nextEdge.getEdge(); Stack<FunctionBody> functionStack = nextEdge.getStack(); // clone stack to have a different representation of the function calls and conditions // for every element functionStack = cloneStack(functionStack); // we do not have a single edge, instead a dynamic multi-edge if (edge == null) { List<CFAEdge> edges = nextEdge.getParentState().getEdgesToChild(childElement); for (CFAEdge inner : edges) { callback.visit(childElement, inner, functionStack); } } else { callback.visit(childElement, edge, functionStack); } // how many parents does the child have? // ignore parents not on the error path int noOfParents = from(childElement.getParents()).filter(in(elementsOnPath)).size(); assert noOfParents >= 1; // handle merging if necessary if (noOfParents > 1) { assert !((edge instanceof CFunctionCallEdge) || (childElement.isTarget())); // this is the end of a condition, determine whether we should continue or backtrack int elemId = childElement.getStateId(); FunctionBody currentFunction = functionStack.peek(); currentFunction.write("goto label_" + elemId + ";"); // get the merge node for that node MergeNode mergeNode = mergeNodes.get(elemId); // if null create new and put in the map if (mergeNode == null) { mergeNode = new MergeNode(elemId); mergeNodes.put(elemId, mergeNode); } // this tells us the number of edges (entering that node) processed so far int noOfProcessedBranches = mergeNode.addBranch(currentFunction); // if all edges are processed if (noOfParents == noOfProcessedBranches) { // all branches are processed, now decide which nodes to remove from the stack List<FunctionBody> incomingStacks = mergeNode.getIncomingStates(); FunctionBody newFunction = processIncomingStacks(incomingStacks); // replace the current function body with the right one functionStack.pop(); functionStack.push(newFunction); newFunction.write("label_" + elemId + ": ;"); } else { return Collections.emptySet(); } } return getRelevantChildrenOfState(childElement, functionStack, elementsOnPath); }