@@ -31,33 +31,50 @@ private class AnalyzedCapturedVariable extends @variable {
3131}
3232
3333/**
34- * Flow analysis for accesses to SSA variables .
34+ * Flow analysis for SSA nodes .
3535 */
36- private class SsaVarAccessAnalysis extends DataFlow:: AnalyzedValueNode {
37- AnalyzedSsaDefinition def ;
36+ private class AnalyzedSsaDefinitionNode extends AnalyzedNode , DataFlow:: SsaDefinitionNode {
37+ override AbstractValue getALocalValue ( ) { result = ssa .( AnalyzedSsaDefinition ) .getAnRhsValue ( ) }
38+ }
3839
39- SsaVarAccessAnalysis ( ) { astNode = def .getVariable ( ) .getAUse ( ) }
40+ /**
41+ * An SSA definition whose right-hand side is a call with non-local data flow.
42+ */
43+ private class SsaDefinitionWithNonLocalFlow extends SsaExplicitDefinition {
44+ CallWithNonLocalAnalyzedReturnFlow source ;
45+
46+ SsaDefinitionWithNonLocalFlow ( ) {
47+ source = getDef ( ) .getSource ( ) .flow ( )
48+ }
4049
41- override AbstractValue getALocalValue ( ) { result = def . getAnRhsValue ( ) }
50+ CallWithNonLocalAnalyzedReturnFlow getSource ( ) { result = source }
4251}
4352
4453/**
45- * Flow analysis for accesses to SSA variables.
46- *
47- * Unlike `SsaVarAccessAnalysis`, this only contributes to `getAValue()`, not `getALocalValue()`.
54+ * Flow analysis for SSA nodes corresponding to `SsaDefinitionWithNonLocalFlow`.
4855 */
49- private class SsaVarAccessWithNonLocalAnalysis extends SsaVarAccessAnalysis {
50- DataFlow :: AnalyzedValueNode src ;
56+ private class AnalyzedSsaDefinitionNodeWithNonLocalAnalysis extends AnalyzedSsaDefinitionNode {
57+ override SsaDefinitionWithNonLocalFlow ssa ;
5158
52- SsaVarAccessWithNonLocalAnalysis ( ) {
53- exists ( VarDef varDef |
54- varDef = def .( SsaExplicitDefinition ) .getDef ( ) and
55- varDef .getSource ( ) .flow ( ) = src and
56- src instanceof CallWithNonLocalAnalyzedReturnFlow
57- )
59+ override AbstractValue getAValue ( ) {
60+ result = ssa .getSource ( ) .getAValue ( )
61+ }
62+ }
63+
64+ /**
65+ * Flow analysis for uses of an SSA variable corresponding to `SsaDefinitionWithNonLocalFlow`.
66+ */
67+ private class AnalyzedSsaVariableUseWithNonLocalFlow extends AnalyzedValueNode {
68+ SsaDefinitionWithNonLocalFlow ssaDef ;
69+
70+ AnalyzedSsaVariableUseWithNonLocalFlow ( ) {
71+ this = DataFlow:: valueNode ( ssaDef .getVariable ( ) .getAUse ( ) )
5872 }
5973
60- override AbstractValue getAValue ( ) { result = src .getAValue ( ) }
74+ override AbstractValue getAValue ( ) {
75+ // Block indefinite values coming from getALocalValue()
76+ result = ssaDef .getSource ( ) .getAValue ( )
77+ }
6178}
6279
6380/**
@@ -620,7 +637,11 @@ private class ReflectiveVarFlow extends DataFlow::AnalyzedValueNode {
620637 )
621638 }
622639
623- override AbstractValue getALocalValue ( ) { result = TIndefiniteAbstractValue ( "eval" ) }
640+ override AbstractValue getALocalValue ( ) {
641+ result = TIndefiniteAbstractValue ( "eval" )
642+ or
643+ result = AnalyzedValueNode .super .getALocalValue ( )
644+ }
624645}
625646
626647/**
@@ -632,7 +653,11 @@ private class ReflectiveVarFlow extends DataFlow::AnalyzedValueNode {
632653private class NamespaceExportVarFlow extends DataFlow:: AnalyzedValueNode {
633654 NamespaceExportVarFlow ( ) { astNode .( VarAccess ) .getVariable ( ) .isNamespaceExport ( ) }
634655
635- override AbstractValue getALocalValue ( ) { result = TIndefiniteAbstractValue ( "namespace" ) }
656+ override AbstractValue getALocalValue ( ) {
657+ result = TIndefiniteAbstractValue ( "namespace" )
658+ or
659+ result = AnalyzedValueNode .super .getALocalValue ( )
660+ }
636661}
637662
638663/**
0 commit comments