@@ -753,9 +753,8 @@ class DefinitionNode extends ControlFlowNode {
753753 or
754754 augstore ( _, this )
755755 or
756- exists ( Assign a | a .getATarget ( ) .( Tuple ) .getAnElt ( ) .getAFlowNode ( ) = this )
757- or
758- exists ( Assign a | a .getATarget ( ) .( List ) .getAnElt ( ) .getAFlowNode ( ) = this )
756+ // `x, y = 1, 2` where LHS is a combination of list or tuples
757+ exists ( Assign a | list_or_tuple_nested_element ( a .getATarget ( ) ) .getAFlowNode ( ) = this )
759758 or
760759 exists ( For for | for .getTarget ( ) .getAFlowNode ( ) = this )
761760 }
@@ -768,6 +767,18 @@ class DefinitionNode extends ControlFlowNode {
768767 }
769768}
770769
770+ private Expr list_or_tuple_nested_element ( Expr list_or_tuple ) {
771+ exists ( Expr elt |
772+ elt = list_or_tuple .( Tuple ) .getAnElt ( )
773+ or
774+ elt = list_or_tuple .( List ) .getAnElt ( )
775+ |
776+ result = elt
777+ or
778+ result = list_or_tuple_nested_element ( elt )
779+ )
780+ }
781+
771782/** A control flow node corresponding to a deletion statement, such as `del x`.
772783 * There can be multiple `DeletionNode`s for each `Delete` such that each
773784 * target has own `DeletionNode`. The CFG for `del a, x.y` looks like:
@@ -887,18 +898,38 @@ private AstNode assigned_value(Expr lhs) {
887898 /* lhs += x => result = (lhs + x) */
888899 exists ( AugAssign a , BinaryExpr b | b = a .getOperation ( ) and result = b and lhs = b .getLeft ( ) )
889900 or
890- /* ..., lhs, ... = ..., result, ... */
891- exists ( Assign a , Tuple target , Tuple values , int index |
892- a .getATarget ( ) = target and
893- a .getValue ( ) = values and
894- lhs = target .getElt ( index ) and
895- result = values .getElt ( index )
896- )
901+ /* ..., lhs, ... = ..., result, ...
902+ * or
903+ * ..., (..., lhs, ...), ... = ..., (..., result, ...), ...
904+ */
905+ exists ( Assign a | nested_sequence_assign ( a .getATarget ( ) , a .getValue ( ) , lhs , result ) )
897906 or
898907 /* for lhs in seq: => `result` is the `for` node, representing the `iter(next(seq))` operation. */
899908 result .( For ) .getTarget ( ) = lhs
900909}
901910
911+ predicate nested_sequence_assign ( Expr left_parent , Expr right_parent ,
912+ Expr left_result , Expr right_result ) {
913+ exists ( int i , Expr left_elem , Expr right_elem
914+ |
915+ (
916+ left_elem = left_parent .( Tuple ) .getElt ( i )
917+ or
918+ left_elem = left_parent .( List ) .getElt ( i )
919+ )
920+ and
921+ (
922+ right_elem = right_parent .( Tuple ) .getElt ( i )
923+ or
924+ right_elem = right_parent .( List ) .getElt ( i )
925+ )
926+ |
927+ left_result = left_elem and right_result = right_elem
928+ or
929+ nested_sequence_assign ( left_elem , right_elem , left_result , right_result )
930+ )
931+ }
932+
902933/** A flow node for a `for` statement. */
903934class ForNode extends ControlFlowNode {
904935
0 commit comments