@@ -462,20 +462,46 @@ private newtype TStoreChain =
462
462
)
463
463
}
464
464
465
+ /**
466
+ * A `StoreChain` represents a series of field lookups that compute the destination of a store.
467
+ * For example, given an assignment such as `a.b.c = x`, there are two `StoreChain`s:
468
+ * One corresponding to the field `b`, and one corresponding to the field `c`. Here, `b` is the parent
469
+ * `StoreChain` of `c`.
470
+ */
465
471
private class StoreChain extends TStoreChain {
466
472
string toString ( ) { none ( ) }
467
473
468
- StoreChainConsCons getParent ( ) { none ( ) }
474
+ /**
475
+ * Gets the parent of this `StoreChain`, if any. For example, for the assignment
476
+ * ```
477
+ * a.b.c = x;
478
+ * ```
479
+ * the parent of `c` is `b`, and `b` has no parent.
480
+ */
481
+ final StoreChainConsCons getParent ( ) { result .getChild ( ) = this }
469
482
483
+ /** Gets the child of this `StoreChain`, if any. */
470
484
StoreChain getChild ( ) { none ( ) }
471
485
486
+ /**
487
+ * Gets the instruction that receives flow from the outermost `StoreChain` of this chain (i.e.,
488
+ * the `StoreChain` with no parent).
489
+ */
472
490
StoreChainEndInstruction getEndInstruction ( ) { none ( ) }
473
491
492
+ /**
493
+ * Gets the instruction that flows to the innermost `StoreChain` of this chain (i.e.,
494
+ * the `StoreChain` with no child).
495
+ */
474
496
Instruction getBeginInstruction ( ) { none ( ) }
475
497
498
+ /** Gets the `FieldAddressInstruction` of this `StoreChain` */
476
499
FieldAddressInstruction getFieldInstruction ( ) { none ( ) }
477
500
501
+ /** Gets the `FieldAddressInstruction` of any `StoreChain` in this chain. */
478
502
FieldAddressInstruction getAFieldInstruction ( ) { none ( ) }
503
+
504
+ final Location getLocation ( ) { result = getFieldInstruction ( ) .getLocation ( ) }
479
505
}
480
506
481
507
private class StoreChainConsNil extends StoreChain , TStoreChainConsNil {
@@ -486,8 +512,6 @@ private class StoreChainConsNil extends StoreChain, TStoreChainConsNil {
486
512
487
513
override string toString ( ) { result = fi .getField ( ) .toString ( ) }
488
514
489
- override StoreChainConsCons getParent ( ) { result = TStoreChainConsCons ( _, this ) }
490
-
491
515
override StoreChainEndInstruction getEndInstruction ( ) { result = end }
492
516
493
517
override Instruction getBeginInstruction ( ) { result = end .getBeginInstruction ( ) }
@@ -505,8 +529,6 @@ private class StoreChainConsCons extends StoreChain, TStoreChainConsCons {
505
529
506
530
override string toString ( ) { result = fi .getField ( ) .toString ( ) + "." + next .toString ( ) }
507
531
508
- override StoreChainConsCons getParent ( ) { result .getChild ( ) = this }
509
-
510
532
override StoreChain getChild ( ) { result = next }
511
533
512
534
override FieldAddressInstruction getFieldInstruction ( ) { result = fi }
@@ -563,18 +585,34 @@ private class LoadChainEndInstructionLoad extends LoadChainEndInstruction, LoadI
563
585
override Instruction getReadValue ( ) { result = getSourceValueOperand ( ) .getAnyDef ( ) }
564
586
}
565
587
588
+ /**
589
+ * A `LoadChain` represents a series of field lookups that compute the source address of a load.
590
+ * For example, given the field lookup in `f(a.b.c)`, there are two `LoadChains`s:
591
+ * One corresponding to the field `b`, and one corresponding to the field `c`. Here, `b` is the parent
592
+ * `LoadChain` of `c`.
593
+ */
566
594
private class LoadChain extends TLoadChain {
567
595
string toString ( ) { none ( ) }
568
596
597
+ /**
598
+ * Gets the instruction that receives flow from the innermost `LoadChain` of this chain (i.e.,
599
+ * the `LoadChain` with no child).
600
+ */
569
601
LoadChainEndInstruction getEndInstruction ( ) { none ( ) }
570
602
603
+ /**
604
+ * Gets the parent of this `LoadChain`, if any. For example in `f(a.b.c)` the parent of `c` is `b`,
605
+ * and `b` has no parent.
606
+ */
571
607
final LoadChainConsCons getParent ( ) { result .getChild ( ) = this }
572
608
609
+ /** Gets the child of this `LoadChain`, if any. */
573
610
LoadChain getChild ( ) { none ( ) }
574
611
612
+ /** Gets the `FieldAddressInstruction` of this `LoadChain` */
575
613
FieldAddressInstruction getFieldInstruction ( ) { none ( ) }
576
614
577
- Location getLocation ( ) { none ( ) }
615
+ final Location getLocation ( ) { result = getFieldInstruction ( ) . getLocation ( ) }
578
616
}
579
617
580
618
private class LoadChainConsNil extends LoadChain , TLoadChainConsNil {
@@ -588,8 +626,6 @@ private class LoadChainConsNil extends LoadChain, TLoadChainConsNil {
588
626
override LoadChainEndInstruction getEndInstruction ( ) { result = end }
589
627
590
628
override FieldAddressInstruction getFieldInstruction ( ) { result = fi }
591
-
592
- override Location getLocation ( ) { result = fi .getLocation ( ) }
593
629
}
594
630
595
631
private class LoadChainConsCons extends LoadChain , TLoadChainConsCons {
@@ -605,11 +641,21 @@ private class LoadChainConsCons extends LoadChain, TLoadChainConsCons {
605
641
override LoadChain getChild ( ) { result = next }
606
642
607
643
override FieldAddressInstruction getFieldInstruction ( ) { result = fi }
608
-
609
- override Location getLocation ( ) { result = fi .getLocation ( ) }
610
644
}
611
645
612
- /** `StoreNode` also extends `ReadStepNode` to participate in reverse read steps. */
646
+ /**
647
+ * A dataflow node generated by a partial definition.
648
+ * The `StoreNode` class extends `ReadStepNode` to participate in reverse read steps.
649
+ * A reverse read is a store step that is "inferred" by the DataFlow library. For example in the
650
+ * assignment:
651
+ * ```
652
+ * a.b.c = x;
653
+ * ```
654
+ * Here, the access path after the store must reflect that a value has been stored into the field `c` of
655
+ * the object at field `b`. The field `c` is added to the access path through a `storeStep`, and the
656
+ * field `b` is inferred by the DataFlow library because there's a read step (reading the field `b`) from
657
+ * the pre update node for `b.c` to the pre update node for `c`.
658
+ */
613
659
private class StoreNode extends TStoreNode , StoreStepNode , ReadStepNode , PartialDefinitionNode {
614
660
StoreChain storeChain ;
615
661
@@ -649,6 +695,7 @@ private class StoreNode extends TStoreNode, StoreStepNode, ReadStepNode, Partial
649
695
}
650
696
}
651
697
698
+ /** A dataflow node generated by loading from an address computed by a sequence of fields lookups. */
652
699
private class LoadNode extends TLoadNode , ReadStepNode {
653
700
LoadChain loadChain ;
654
701
0 commit comments