@@ -636,10 +636,52 @@ abstract class StackVariableReachabilityWithReassignment extends StackVariableRe
636636 )
637637 }
638638
639+ private predicate bbSuccessorEntryReaches (
640+ BasicBlock bb , SemanticStackVariable v , ControlFlowNode node ,
641+ boolean skipsFirstLoopAlwaysTrueUponEntry
642+ ) {
643+ exists ( BasicBlock succ , boolean succSkipsFirstLoopAlwaysTrueUponEntry |
644+ bbSuccessorEntryReachesLoopInvariant0 ( bb , succ , skipsFirstLoopAlwaysTrueUponEntry ,
645+ succSkipsFirstLoopAlwaysTrueUponEntry )
646+ |
647+ revBbEntryReachesLocally ( succ , v , node , this ) and
648+ succSkipsFirstLoopAlwaysTrueUponEntry = false
649+ or
650+ not isBarrier ( succ .getNode ( _) , v ) and
651+ bbSuccessorEntryReaches ( succ , v , node , succSkipsFirstLoopAlwaysTrueUponEntry )
652+ )
653+ }
654+
655+ private predicate reaches0 ( ControlFlowNode source , SemanticStackVariable v , ControlFlowNode sink ) {
656+ /*
657+ * Implementation detail: the predicates in this class are a generalization of
658+ * those in DefinitionsAndUses.qll, and should be kept in sync.
659+ *
660+ * Unfortunately, caching of abstract predicates does not work well, so the
661+ * predicates in DefinitionsAndUses.qll cannot use this library.
662+ */
663+
664+ exists ( BasicBlock bb , int i |
665+ isSource ( source , v ) and
666+ bb .getNode ( i ) = source and
667+ not bb .isUnreachable ( )
668+ |
669+ exists ( int j |
670+ j > i and
671+ sink = bb .getNode ( j ) and
672+ isSink ( sink , v ) and
673+ not isBarrier ( bb .getNode ( pragma [ only_bind_into ] ( [ i + 1 .. j - 1 ] ) ) , v )
674+ )
675+ or
676+ not exists ( int k | isBarrier ( bb .getNode ( k ) , v ) | k > i ) and
677+ bbSuccessorEntryReaches ( bb , v , sink , _)
678+ )
679+ }
680+
639681 private predicate reassignment (
640682 ControlFlowNode source , SemanticStackVariable v , ControlFlowNode def , SemanticStackVariable v0
641683 ) {
642- StackVariableReachability . super . reaches ( source , v , def ) and
684+ reaches0 ( source , v , def ) and
643685 exprDefinition ( v0 , def , v .getAnAccess ( ) )
644686 }
645687
@@ -705,11 +747,11 @@ abstract class StackVariableReachabilityExt extends string {
705747 boolean skipsFirstLoopAlwaysTrueUponEntry
706748 ) {
707749 exists ( BasicBlock succ , boolean succSkipsFirstLoopAlwaysTrueUponEntry |
708- bbSuccessorEntryReachesLoopInvariant ( bb , succ , skipsFirstLoopAlwaysTrueUponEntry ,
750+ bbSuccessorEntryReachesLoopInvariant0 ( bb , succ , skipsFirstLoopAlwaysTrueUponEntry ,
709751 succSkipsFirstLoopAlwaysTrueUponEntry ) and
710752 not isBarrier ( source , bb .getEnd ( ) , succ .getStart ( ) , v )
711753 |
712- bbEntryReachesLocally ( source , succ , v , node ) and
754+ this . bbEntryReachesLocally ( source , succ , v , node ) and
713755 succSkipsFirstLoopAlwaysTrueUponEntry = false
714756 or
715757 not exists ( int k | isBarrier ( source , succ .getNode ( k ) , succ .getNode ( k + 1 ) , v ) ) and
0 commit comments