@@ -33,7 +33,9 @@ public class ContextSensitivePathBuilder extends ConcurrentAbstractionPathBuilde
3333 protected ConcurrentIdentityHashMultiMap <Abstraction , SourceContextAndPath > pathCache = new ConcurrentIdentityHashMultiMap <>();
3434
3535 // Set holds all paths that reach an already cached subpath
36- protected ConcurrentHashSet <Pair <SourceContextAndPath , SourceContextAndPath >> deferredPaths = new ConcurrentHashSet <>();
36+ protected ConcurrentHashSet <SourceContextAndPath > deferredPaths = new ConcurrentHashSet <>();
37+ // Set holds all paths that reach a source
38+ protected ConcurrentHashSet <SourceContextAndPath > sourceReachingScaps = new ConcurrentHashSet <>();
3739
3840 /**
3941 * Creates a new instance of the {@link ContextSensitivePathBuilder} class
@@ -78,12 +80,6 @@ public void run() {
7880 final Set <SourceContextAndPath > paths = pathCache .get (abstraction );
7981 Abstraction pred = abstraction .getPredecessor ();
8082
81- // Skip abstractions that don't contain any new information. This might
82- // be the case when a turn unit was added to the abstraction.
83- while (pred != null && pred .getCurrentStmt () == null && pred .getCorrespondingCallSite () == null ) {
84- pred = pred .getPredecessor ();
85- }
86-
8783 if (pred != null && paths != null ) {
8884 for (SourceContextAndPath scap : paths ) {
8985 // Process the predecessor
@@ -110,7 +106,7 @@ private void processAndQueue(Abstraction pred, SourceContextAndPath scap) {
110106 case CACHED :
111107 // In case we already know the subpath, we do append the path after the path
112108 // builder terminated
113- deferredPaths .add (new Pair <>( scap , p . getScap ()) );
109+ deferredPaths .add (scap );
114110 break ;
115111 case INFEASIBLE_OR_MAX_PATHS_REACHED :
116112 // Nothing to do
@@ -128,7 +124,8 @@ private ProcessingResult processPredecessor(SourceContextAndPath scap, Abstracti
128124 if (extendedScap == null )
129125 return ProcessingResult .INFEASIBLE_OR_MAX_PATHS_REACHED ();
130126
131- checkForSource (pred , extendedScap );
127+ if (checkForSource (pred , extendedScap ))
128+ sourceReachingScaps .add (extendedScap );
132129 return pathCache .put (pred , extendedScap ) ? ProcessingResult .NEW ()
133130 : ProcessingResult .CACHED (extendedScap );
134131 }
@@ -176,7 +173,8 @@ private ProcessingResult processPredecessor(SourceContextAndPath scap, Abstracti
176173 }
177174
178175 // Add the new path
179- checkForSource (pred , extendedScap );
176+ if (checkForSource (pred , extendedScap ))
177+ sourceReachingScaps .add (extendedScap );
180178
181179 final int maxPaths = config .getPathConfiguration ().getMaxPathsPerAbstraction ();
182180 if (maxPaths > 0 ) {
@@ -289,27 +287,14 @@ public void computeTaintPaths(Set<AbstractionAtSink> res) {
289287 }
290288
291289 /**
292- * Uses the cached path to extend the current path
293- *
294- * @param scap SourceContextAndPath of the current abstraction
295- * @param cachedScap cached SourceContextAndPath to extend scap
290+ * Tries to fill up deferred paths toward a source.
296291 */
297- protected void buildFullPathFromCache (SourceContextAndPath scap , SourceContextAndPath cachedScap ) {
298- // Try to extend scap with cachedScap
299- Stack <Pair <SourceContextAndPath , SourceContextAndPath >> workStack = new Stack <>();
300- workStack .push (new Pair <>(scap , cachedScap ));
301- while (!workStack .isEmpty ()) {
302- Pair <SourceContextAndPath , SourceContextAndPath > p = workStack .pop ();
303- scap = p .getO1 ();
304- cachedScap = p .getO2 ();
305-
306- SourceContextAndPath extendedScap = scap .extendPath (cachedScap );
307- if (extendedScap != null ) {
308- Abstraction last = extendedScap .getLastAbstraction ();
309- // Try to build the path further using the cache if we didn't reach a source
310- if (!checkForSource (last , extendedScap ))
311- for (SourceContextAndPath preds : pathCache .get (last .getPredecessor ()))
312- workStack .push (new Pair <>(extendedScap , preds ));
292+ protected void buildPathsFromCache () {
293+ for (SourceContextAndPath deferredScap : deferredPaths ) {
294+ for (SourceContextAndPath sourceScap : sourceReachingScaps ) {
295+ SourceContextAndPath fullScap = deferredScap .extendPath (sourceScap );
296+ if (fullScap != null )
297+ checkForSource (fullScap .getLastAbstraction (), fullScap );
313298 }
314299 }
315300 }
@@ -318,9 +303,7 @@ protected void buildFullPathFromCache(SourceContextAndPath scap, SourceContextAn
318303 * Method that is called when the taint paths have been computed
319304 */
320305 protected void onTaintPathsComputed () {
321- for (Pair <SourceContextAndPath , SourceContextAndPath > deferredPair : deferredPaths ) {
322- buildFullPathFromCache (deferredPair .getO1 (), deferredPair .getO2 ());
323- }
306+ buildPathsFromCache ();
324307 }
325308
326309 /**
0 commit comments