private void continueTraversal(int pValue, SMGSingleLinkedListCandidate pCandidate) {
    SMGEdgePointsTo pt = smg.getPointer(pValue);
    SMGObject object = pt.getObject();
    if (!candidates.containsKey(object)) {
      startTraversal(object);
    }

    if (inboundPointers.get(pValue) > 1) {
      return;
    }

    Map<Integer, SMGSingleLinkedListCandidate> objectCandidates = candidates.get(object);
    Integer offset = pCandidate.getOffset();

    if (!objectCandidates.containsKey(offset)) {
      // try to infer a pointer presence: either NULL, or uninitialized
      if (smg.isCoveredByNullifiedBlocks(object, offset, AnonymousTypes.dummyPointer)) {
        objectCandidates.put(offset, new SMGSingleLinkedListCandidate(object, offset, 1));
      }
    }

    if (objectCandidates.containsKey(offset)) {
      SMGSingleLinkedListCandidate myCandidate = objectCandidates.get(offset);
      if (pCandidate.isCompatibleWith(myCandidate)) {
        objectCandidates.remove(offset);
        pCandidate.addLength(myCandidate.getLength());
      }
    }
  }
 private void startTraversal(SMGObject pObject) {
   if (candidates.containsKey(pObject)) {
     // Processed already in continueTraversal
     return;
   }
   candidates.put(pObject, new HashMap<Integer, SMGSingleLinkedListCandidate>());
   for (SMGEdgeHasValue hv : smg.getHVEdges(SMGEdgeHasValueFilter.objectFilter(pObject))) {
     if (smg.isPointer(hv.getValue())) {
       SMGSingleLinkedListCandidate candidate =
           new SMGSingleLinkedListCandidate(pObject, hv.getOffset(), 1);
       candidates.get(pObject).put(hv.getOffset(), candidate);
       continueTraversal(hv.getValue(), candidate);
     }
   }
 }
  @Test
  public void simpleListTest() {
    CLangSMG smg = new CLangSMG(MachineModel.LINUX64);

    SMGEdgeHasValue root = TestHelpers.createGlobalList(smg, 5, 16, 8, "pointer");

    SMGSingleLinkedListFinder finder = new SMGSingleLinkedListFinder(1);
    Set<SMGAbstractionCandidate> candidates = finder.traverse(smg);
    Assert.assertEquals(1, candidates.size());
    SMGAbstractionCandidate candidate = Iterables.getOnlyElement(candidates);
    Assert.assertTrue(candidate instanceof SMGSingleLinkedListCandidate);
    SMGSingleLinkedListCandidate sllCandidate = (SMGSingleLinkedListCandidate) candidate;
    Assert.assertEquals(5, sllCandidate.getLength());
    Assert.assertEquals(8, sllCandidate.getOffset());
    SMGRegion expectedStart = (SMGRegion) smg.getPointer(root.getValue()).getObject();
    Assert.assertSame(expectedStart, sllCandidate.getStart());
  }
  @Override
  public Set<SMGAbstractionCandidate> traverse(CLangSMG pSmg) {
    smg = pSmg;

    buildInboundPointers();

    for (SMGObject object : smg.getHeapObjects()) {
      startTraversal(object);
    }

    Set<SMGAbstractionCandidate> returnSet = new HashSet<>();
    for (Map<Integer, SMGSingleLinkedListCandidate> objCandidates : candidates.values()) {
      for (SMGSingleLinkedListCandidate candidate : objCandidates.values()) {
        if (candidate.getLength() > seqLengthThreshold) {
          returnSet.add(candidate);
        }
      }
    }
    return Collections.unmodifiableSet(returnSet);
  }
  @Test
  public void listWithInboundPointersTest() {
    CLangSMG smg = new CLangSMG(MachineModel.LINUX64);
    Integer tail = TestHelpers.createList(smg, 4, 16, 8, "tail");

    SMGEdgeHasValue head = TestHelpers.createGlobalList(smg, 3, 16, 8, "head");

    SMGObject inside = new SMGRegion(16, "pointed_at");
    SMGEdgeHasValue tailConnection =
        new SMGEdgeHasValue(AnonymousTypes.dummyPointer, 8, inside, tail);

    Integer addressOfInside = SMGValueFactory.getNewValue();
    SMGEdgePointsTo insidePT = new SMGEdgePointsTo(addressOfInside, inside, 0);
    SMGRegion inboundPointer = new SMGRegion(8, "inbound_pointer");
    SMGEdgeHasValue inboundPointerConnection =
        new SMGEdgeHasValue(AnonymousTypes.dummyPointer, 0, inboundPointer, addressOfInside);

    SMGObject lastFromHead = smg.getPointer(head.getValue()).getObject();
    SMGEdgeHasValue connection = null;
    do {
      SMGEdgeHasValueFilter filter =
          SMGEdgeHasValueFilter.objectFilter(lastFromHead).filterAtOffset(8);
      Set<SMGEdgeHasValue> connections = smg.getHVEdges(filter);
      connection = null;
      if (connections.size() > 0) {
        connection = Iterables.getOnlyElement(connections);
        lastFromHead = smg.getPointer(connection.getValue()).getObject();
      }
    } while (connection != null);

    for (SMGEdgeHasValue hv : smg.getHVEdges(SMGEdgeHasValueFilter.objectFilter(lastFromHead))) {
      smg.removeHasValueEdge(hv);
    }

    SMGEdgeHasValue headConnection =
        new SMGEdgeHasValue(AnonymousTypes.dummyPointer, 8, lastFromHead, addressOfInside);

    SMGRegion tailPointer = new SMGRegion(8, "tail_pointer");
    SMGEdgeHasValue tailPointerConnection =
        new SMGEdgeHasValue(AnonymousTypes.dummyPointer, 0, tailPointer, tail);

    smg.addGlobalObject(tailPointer);
    smg.addHasValueEdge(tailPointerConnection);

    smg.addHeapObject(inside);
    smg.addValue(addressOfInside);
    smg.addPointsToEdge(insidePT);

    smg.addGlobalObject(inboundPointer);
    smg.addHasValueEdge(inboundPointerConnection);

    smg.addHasValueEdge(tailConnection);
    smg.addHasValueEdge(headConnection);

    SMGSingleLinkedListFinder finder = new SMGSingleLinkedListFinder(1);
    Set<SMGAbstractionCandidate> candidates = finder.traverse(smg);
    Assert.assertEquals(2, candidates.size());

    boolean sawHead = false;
    boolean sawTail = false;
    for (SMGAbstractionCandidate candidate : candidates) {
      SMGSingleLinkedListCandidate sllCandidate = (SMGSingleLinkedListCandidate) candidate;
      if (sllCandidate.getLength() == 3) {
        Assert.assertSame(smg.getPointer(head.getValue()).getObject(), sllCandidate.getStart());
        Assert.assertFalse(sawHead);
        sawHead = true;
      } else if (sllCandidate.getLength() == 4) {
        Assert.assertSame(smg.getPointer(tail).getObject(), sllCandidate.getStart());
        Assert.assertFalse(sawTail);
      } else {
        Assert.fail("We should not see any candidates with length other than 3 or 4");
      }
    }
  }
 private void buildInboundPointers() {
   for (Integer pointer : smg.getPTEdges().keySet()) {
     inboundPointers.put(
         pointer, smg.getHVEdges(new SMGEdgeHasValueFilter().filterHavingValue(pointer)).size());
   }
 }