@@ -18,17 +18,17 @@ private import codeql.util.Unit
18
18
19
19
/**
20
20
* The IR dataflow graph consists of the following nodes:
21
- * - `Node0`, which injects most instructions and operands directly into the dataflow graph.
21
+ * - `Node0`, which injects most instructions and operands directly into the
22
+ * dataflow graph.
22
23
* - `VariableNode`, which is used to model flow through global variables.
23
- * - `PostFieldUpdateNode`, which is used to model the state of a field after a value has been stored
24
- * into an address after a number of loads.
25
- * - `SsaPhiNode`, which represents phi nodes as computed by the shared SSA library.
26
- * - `IndirectArgumentOutNode`, which represents the value of an argument (and its indirections) after
27
- * it leaves a function call.
28
- * - `RawIndirectOperand`, which represents the value of `operand` after loading the address a number
29
- * of times.
30
- * - `RawIndirectInstruction`, which represents the value of `instr` after loading the address a number
31
- * of times.
24
+ * - `PostUpdateNodeImpl`, which is used to model the state of an object after
25
+ * an update after a number of loads.
26
+ * - `SsaPhiNode`, which represents phi nodes as computed by the shared SSA
27
+ * library.
28
+ * - `RawIndirectOperand`, which represents the value of `operand` after
29
+ * loading the address a number of times.
30
+ * - `RawIndirectInstruction`, which represents the value of `instr` after
31
+ * loading the address a number of times.
32
32
*/
33
33
cached
34
34
private newtype TIRDataFlowNode =
@@ -37,14 +37,13 @@ private newtype TIRDataFlowNode =
37
37
indirectionIndex =
38
38
[ getMinIndirectionsForType ( var .getUnspecifiedType ( ) ) .. Ssa:: getMaxIndirectionsForType ( var .getUnspecifiedType ( ) ) ]
39
39
} or
40
- TPostFieldUpdateNode ( FieldAddress operand , int indirectionIndex ) {
41
- indirectionIndex =
42
- [ 1 .. Ssa:: countIndirectionsForCppType ( operand .getObjectAddress ( ) .getResultLanguageType ( ) ) ]
43
- } or
44
- TSsaPhiNode ( Ssa:: PhiNode phi ) or
45
- TIndirectArgumentOutNode ( ArgumentOperand operand , int indirectionIndex ) {
40
+ TPostUpdateNodeImpl ( Operand operand , int indirectionIndex ) {
41
+ operand = any ( FieldAddress fa ) .getObjectAddressOperand ( ) and
42
+ indirectionIndex = [ 1 .. Ssa:: countIndirectionsForCppType ( Ssa:: getLanguageType ( operand ) ) ]
43
+ or
46
44
Ssa:: isModifiableByCall ( operand , indirectionIndex )
47
45
} or
46
+ TSsaPhiNode ( Ssa:: PhiNode phi ) or
48
47
TRawIndirectOperand0 ( Node0Impl node , int indirectionIndex ) {
49
48
Ssa:: hasRawIndirectOperand ( node .asOperand ( ) , indirectionIndex )
50
49
} or
@@ -84,7 +83,7 @@ private predicate parameterIsRedefined(Parameter p) {
84
83
class FieldAddress extends Operand {
85
84
FieldAddressInstruction fai ;
86
85
87
- FieldAddress ( ) { fai = this .getDef ( ) }
86
+ FieldAddress ( ) { fai = this .getDef ( ) and not Ssa :: ignoreOperand ( this ) }
88
87
89
88
/** Gets the field associated with this instruction. */
90
89
Field getField ( ) { result = fai .getField ( ) }
@@ -550,37 +549,44 @@ Type stripPointer(Type t) {
550
549
result = t .( FunctionPointerIshType ) .getBaseType ( )
551
550
}
552
551
553
- /**
554
- * INTERNAL: do not use.
555
- *
556
- * The node representing the value of a field after it has been updated.
557
- */
558
- class PostFieldUpdateNode extends TPostFieldUpdateNode , PartialDefinitionNode {
552
+ private class PostUpdateNodeImpl extends PartialDefinitionNode , TPostUpdateNodeImpl {
559
553
int indirectionIndex ;
560
- FieldAddress fieldAddress ;
554
+ Operand operand ;
561
555
562
- PostFieldUpdateNode ( ) { this = TPostFieldUpdateNode ( fieldAddress , indirectionIndex ) }
556
+ PostUpdateNodeImpl ( ) { this = TPostUpdateNodeImpl ( operand , indirectionIndex ) }
563
557
564
- override Declaration getFunction ( ) { result = fieldAddress .getUse ( ) .getEnclosingFunction ( ) }
558
+ override Declaration getFunction ( ) { result = operand .getUse ( ) .getEnclosingFunction ( ) }
565
559
566
560
override Declaration getEnclosingCallable ( ) { result = this .getFunction ( ) }
567
561
568
- FieldAddress getFieldAddress ( ) { result = fieldAddress }
569
-
570
- Field getUpdatedField ( ) { result = fieldAddress .getField ( ) }
562
+ /** Gets the operand associated with this node. */
563
+ Operand getOperand ( ) { result = operand }
571
564
565
+ /** Gets the indirection index associated with this node. */
572
566
int getIndirectionIndex ( ) { result = indirectionIndex }
573
567
574
- override Node getPreUpdateNode ( ) {
575
- hasOperandAndIndex ( result , pragma [ only_bind_into ] ( fieldAddress ) .getObjectAddressOperand ( ) ,
576
- indirectionIndex )
577
- }
568
+ override Location getLocationImpl ( ) { result = operand .getLocation ( ) }
578
569
579
- override Expr getDefinedExpr ( ) {
580
- result = fieldAddress .getObjectAddress ( ) .getUnconvertedResultExpression ( )
570
+ final override Node getPreUpdateNode ( ) { hasOperandAndIndex ( result , operand , indirectionIndex ) }
571
+
572
+ final override Expr getDefinedExpr ( ) {
573
+ result = operand .getDef ( ) .getUnconvertedResultExpression ( )
581
574
}
575
+ }
576
+
577
+ /**
578
+ * INTERNAL: do not use.
579
+ *
580
+ * The node representing the value of a field after it has been updated.
581
+ */
582
+ class PostFieldUpdateNode extends PostUpdateNodeImpl {
583
+ FieldAddress fieldAddress ;
582
584
583
- override Location getLocationImpl ( ) { result = fieldAddress .getLocation ( ) }
585
+ PostFieldUpdateNode ( ) { operand = fieldAddress .getObjectAddressOperand ( ) }
586
+
587
+ FieldAddress getFieldAddress ( ) { result = fieldAddress }
588
+
589
+ Field getUpdatedField ( ) { result = this .getFieldAddress ( ) .getField ( ) }
584
590
585
591
override string toStringImpl ( ) { result = this .getPreUpdateNode ( ) + " [post update]" }
586
592
}
@@ -816,13 +822,8 @@ class IndirectReturnNode extends Node {
816
822
* A node representing the indirection of a value after it
817
823
* has been returned from a function.
818
824
*/
819
- class IndirectArgumentOutNode extends Node , TIndirectArgumentOutNode , PartialDefinitionNode {
820
- ArgumentOperand operand ;
821
- int indirectionIndex ;
822
-
823
- IndirectArgumentOutNode ( ) { this = TIndirectArgumentOutNode ( operand , indirectionIndex ) }
824
-
825
- int getIndirectionIndex ( ) { result = indirectionIndex }
825
+ class IndirectArgumentOutNode extends PostUpdateNodeImpl {
826
+ override ArgumentOperand operand ;
826
827
827
828
int getArgumentIndex ( ) {
828
829
exists ( CallInstruction call | call .getArgumentOperand ( result ) = operand )
@@ -834,12 +835,6 @@ class IndirectArgumentOutNode extends Node, TIndirectArgumentOutNode, PartialDef
834
835
835
836
Function getStaticCallTarget ( ) { result = this .getCallInstruction ( ) .getStaticCallTarget ( ) }
836
837
837
- override Declaration getEnclosingCallable ( ) { result = this .getFunction ( ) }
838
-
839
- override Declaration getFunction ( ) { result = this .getCallInstruction ( ) .getEnclosingFunction ( ) }
840
-
841
- override Node getPreUpdateNode ( ) { hasOperandAndIndex ( result , operand , indirectionIndex ) }
842
-
843
838
override string toStringImpl ( ) {
844
839
// This string should be unique enough to be helpful but common enough to
845
840
// avoid storing too many different strings.
@@ -848,10 +843,6 @@ class IndirectArgumentOutNode extends Node, TIndirectArgumentOutNode, PartialDef
848
843
not exists ( this .getStaticCallTarget ( ) ) and
849
844
result = "output argument"
850
845
}
851
-
852
- override Location getLocationImpl ( ) { result = operand .getLocation ( ) }
853
-
854
- override Expr getDefinedExpr ( ) { result = operand .getDef ( ) .getUnconvertedResultExpression ( ) }
855
846
}
856
847
857
848
/**
0 commit comments