@@ -36,7 +36,7 @@ private import ExprNodes
3636 * constant value in some cases.
3737 */
3838private module Propagation {
39- private ExprCfgNode getSource ( VariableReadAccessCfgNode read ) {
39+ ExprCfgNode getSource ( VariableReadAccessCfgNode read ) {
4040 exists ( Ssa:: WriteDefinition def |
4141 def .assigns ( result ) and
4242 read = def .getARead ( )
@@ -511,7 +511,8 @@ private module Cached {
511511import Cached
512512
513513/**
514- * Holds if `e` is an array constructed from an array literal.
514+ * Holds if the control flow node `e` refers to an array constructed from the
515+ * array literal `arr`.
515516 * Example:
516517 * ```rb
517518 * [1, 2, 3]
@@ -523,9 +524,33 @@ predicate isArrayConstant(ExprCfgNode e, ArrayLiteralCfgNode arr) {
523524 // [...]
524525 e = arr
525526 or
526- // C = [...]; C
527- e . ( ExprNodes :: ConstantReadAccessCfgNode ) . getExpr ( ) . getValue ( ) . getDesugared ( ) = arr . getExpr ( )
527+ // e = [...]; e
528+ isArrayConstant ( getSource ( e ) , arr )
528529 or
529- // x = [...]; x
530- exists ( Ssa:: WriteDefinition def | def .getARead ( ) = e and def .assigns ( arr ) )
530+ isArrayExpr ( e .getExpr ( ) , arr )
531+ }
532+
533+ /**
534+ * Holds if the expression `e` refers to an array constructed from the array literal `arr`.
535+ */
536+ predicate isArrayExpr ( Expr e , ArrayLiteralCfgNode arr ) {
537+ // e = [...]
538+ e = arr .getExpr ( )
539+ or
540+ // Like above, but handles the desugaring of array literals to Array.[] calls.
541+ e .getDesugared ( ) = arr .getExpr ( )
542+ or
543+ // A = [...]; A
544+ // A = a; A
545+ isArrayExpr ( e .( ConstantReadAccess ) .getValue ( ) , arr )
546+ or
547+ // Recurse via CFG nodes. Necessary for example in:
548+ // a = [...]
549+ // A = a
550+ // A
551+ //
552+ // We map from A to a via ConstantReadAccess::getValue, yielding the Expr a.
553+ // To get to [...] we need to go via getSource(ExprCfgNode e), so we find a
554+ // CFG node for a and call `isArrayConstant`.
555+ isArrayConstant ( e .getAControlFlowNode ( ) , arr )
531556}
0 commit comments