private boolean checkIds(CFANode node) {
    // This is the (original) recursive algorithm.
    // We keep this implementation as an assertion check
    // to check that the non-recursive algorithm assigns exactly(!) the same ids.
    // Even slight variations have been found to cause performance differences,
    // although we are not sure why.

    if (!visited.add(node)) {
      // already handled, do nothing
      return true;
    }

    for (CFANode successor : CFAUtils.successorsOf(node)) {
      checkIds(successor);
    }

    // node.setReversePostorderId(reversePostorderId2++);
    assert node.getReversePostorderId() == reversePostorderId2++
        : "Node "
            + node
            + " got "
            + node.getReversePostorderId()
            + ", but should get "
            + (reversePostorderId2 - 1);
    return true;
  }
Example #2
0
 private void step4() {
   for (int i = 2; i < n; i++) {
     CFANode w = vertex.get(i);
     NodeInfo infow = map.get(w);
     CFANode d = dom.get(w);
     if (!(d.equals(vertex.get(infow.semi)))) {
       CFANode dd = dom.get(d);
       dom.put(d, dd);
     }
   }
   if (mode == 0) {
     dom.put(entry, null);
   } else {
     dom.put(exit, null);
   }
 }
Example #3
0
  private void dfs(CFANode pNode) {
    NodeInfo infov = map.get(pNode);
    n = n + 1;
    infov.semi = n;
    vertex.set(n, pNode);
    infov.label = pNode;
    infov.ancestor = null;
    int m;
    if (mode == 0) {
      m = pNode.getNumLeavingEdges();
    } else {
      m = pNode.getNumEnteringEdges();
    }
    FunctionSummaryEdge e;
    CFANode w;
    if (mode == 0) {
      e = pNode.getLeavingSummaryEdge();
    } else {
      e = pNode.getEnteringSummaryEdge();
    }

    if (e != null) {
      if (mode == 0) {
        w = e.getSuccessor();
      } else {
        w = e.getPredecessor();
      }
      NodeInfo infow = map.get(w);
      if (infow.semi == 0) {
        infow.parent = pNode;
        dfs(w);
      }
      infow.pred.add(pNode);
    }
    // else{
    for (int i = 0; i < m; i++) {
      if (mode == 0) {
        w = pNode.getLeavingEdge(i).getSuccessor();
      } else {
        w = pNode.getEnteringEdge(i).getPredecessor();
      }
      NodeInfo infow = map.get(w);
      if (infow.semi == 0) {
        infow.parent = pNode;
        dfs(w);
      }
      infow.pred.add(pNode);
    }
    //   }
  }
  public void assignSorting(final CFANode start) {
    // This is an iterative version of the original algorithm that is now in checkIds().
    // We store the state of the function in two stacks:
    // - the current node (variable "node" in checkIds())
    // - the iterator over the current node's successors (this is state hidden in the for-each loop
    // in checkIds())
    // Together, these two items form a "stack frame".

    final Set<CFANode> visited = new HashSet<>();

    final Deque<CFANode> nodeStack = new ArrayDeque<>();
    final Deque<Iterator<CFANode>> iteratorStack =
        new LinkedList<>(); // ArrayDeque doesn't work here because we store nulls

    nodeStack.push(start);
    iteratorStack.push(null);

    while (!nodeStack.isEmpty()) {
      assert nodeStack.size() == iteratorStack.size();

      final CFANode node = nodeStack.peek();
      Iterator<CFANode> successors = iteratorStack.peek();

      if (successors == null) {
        // Entering this stack frame.
        // This part of the code corresponds to the code in checkIds()
        // before the for loop.

        if (!visited.add(node)) {
          // already handled, do nothing

          // Do a simulated "return".
          nodeStack.pop();
          iteratorStack.pop();
          continue;
        }

        // enter the for loop
        successors = CFAUtils.successorsOf(node).iterator();
        iteratorStack.pop();
        iteratorStack.push(successors);
      }

      if (successors.hasNext()) {
        // "recursive call"
        // This part of the code corresponds to the code in checkIds()
        // during the loop.
        CFANode successor = successors.next();

        // Do a simulated "function call" by pushing something on the stacks,
        // creating a new stack frame.
        nodeStack.push(successor);
        iteratorStack.push(null);

      } else {
        // All children handled.
        // This part of the code corresponds to the code in checkIds()
        // after the loop.
        node.setReversePostorderId(reversePostorderId++);

        // Do a simulated "return".
        nodeStack.pop();
        iteratorStack.pop();
      }
    }
    assert checkIds(start);
  }
  public void writeCoverageReport(
      final PrintStream pStatisticsOutput, final ReachedSet pReached, final CFA pCfa) {

    if (!enabled) {
      return;
    }

    Multiset<FunctionEntryNode> reachedLocations = getFunctionEntriesFromReached(pReached);

    Map<String, FileCoverageInformation> infosPerFile = new HashMap<>();

    // Add information about existing functions
    for (FunctionEntryNode entryNode : pCfa.getAllFunctionHeads()) {
      final FileLocation loc = entryNode.getFileLocation();
      if (loc.getStartingLineNumber() == 0) {
        // dummy location
        continue;
      }
      final String functionName = entryNode.getFunctionName();
      final FileCoverageInformation infos = getFileInfoTarget(loc, infosPerFile);

      final int startingLine = loc.getStartingLineInOrigin();
      final int endingLine = loc.getEndingLineInOrigin();

      infos.addExistingFunction(functionName, startingLine, endingLine);

      if (reachedLocations.contains(entryNode)) {
        infos.addVisitedFunction(entryNode.getFunctionName(), reachedLocations.count(entryNode));
      }
    }

    // Add information about existing locations
    for (CFANode node : pCfa.getAllNodes()) {
      for (int i = 0; i < node.getNumLeavingEdges(); i++) {
        handleExistedEdge(node.getLeavingEdge(i), infosPerFile);
      }
    }

    Set<CFANode> reachedNodes =
        from(pReached).transform(EXTRACT_LOCATION).filter(notNull()).toSet();
    // Add information about visited locations
    for (AbstractState state : pReached) {
      ARGState argState = AbstractStates.extractStateByType(state, ARGState.class);
      if (argState != null) {
        for (ARGState child : argState.getChildren()) {
          if (!child.isCovered()) {
            List<CFAEdge> edges = argState.getEdgesToChild(child);
            if (edges.size() > 1) {
              for (CFAEdge innerEdge : edges) {
                handleCoveredEdge(innerEdge, infosPerFile);
              }

              // BAM produces paths with no edge connection thus the list will be empty
            } else if (!edges.isEmpty()) {
              handleCoveredEdge(Iterables.getOnlyElement(edges), infosPerFile);
            }
          }
        }
      } else {
        // Simple kind of analysis
        // Cover all edges from reached nodes
        // It is less precise, but without ARG it is impossible to know what path we chose
        CFANode node = AbstractStates.extractLocation(state);
        for (int i = 0; i < node.getNumLeavingEdges(); i++) {
          CFAEdge edge = node.getLeavingEdge(i);
          if (reachedNodes.contains(edge.getSuccessor())) {
            handleCoveredEdge(edge, infosPerFile);
          }
        }
      }
    }

    for (CoverageWriter w : reportWriters) {
      w.write(infosPerFile, pStatisticsOutput);
    }
  }