@@ -18,17 +18,17 @@ private import codeql.util.Unit
1818
1919/**
2020 * 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.
2223 * - `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.
3232 */
3333cached
3434private newtype TIRDataFlowNode =
@@ -37,14 +37,13 @@ private newtype TIRDataFlowNode =
3737 indirectionIndex =
3838 [ getMinIndirectionsForType ( var .getUnspecifiedType ( ) ) .. Ssa:: getMaxIndirectionsForType ( var .getUnspecifiedType ( ) ) ]
3939 } 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
4644 Ssa:: isModifiableByCall ( operand , indirectionIndex )
4745 } or
46+ TSsaPhiNode ( Ssa:: PhiNode phi ) or
4847 TRawIndirectOperand0 ( Node0Impl node , int indirectionIndex ) {
4948 Ssa:: hasRawIndirectOperand ( node .asOperand ( ) , indirectionIndex )
5049 } or
@@ -84,7 +83,7 @@ private predicate parameterIsRedefined(Parameter p) {
8483class FieldAddress extends Operand {
8584 FieldAddressInstruction fai ;
8685
87- FieldAddress ( ) { fai = this .getDef ( ) }
86+ FieldAddress ( ) { fai = this .getDef ( ) and not Ssa :: ignoreOperand ( this ) }
8887
8988 /** Gets the field associated with this instruction. */
9089 Field getField ( ) { result = fai .getField ( ) }
@@ -550,37 +549,44 @@ Type stripPointer(Type t) {
550549 result = t .( FunctionPointerIshType ) .getBaseType ( )
551550}
552551
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 {
559553 int indirectionIndex ;
560- FieldAddress fieldAddress ;
554+ Operand operand ;
561555
562- PostFieldUpdateNode ( ) { this = TPostFieldUpdateNode ( fieldAddress , indirectionIndex ) }
556+ PostUpdateNodeImpl ( ) { this = TPostUpdateNodeImpl ( operand , indirectionIndex ) }
563557
564- override Declaration getFunction ( ) { result = fieldAddress .getUse ( ) .getEnclosingFunction ( ) }
558+ override Declaration getFunction ( ) { result = operand .getUse ( ) .getEnclosingFunction ( ) }
565559
566560 override Declaration getEnclosingCallable ( ) { result = this .getFunction ( ) }
567561
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 }
571564
565+ /** Gets the indirection index associated with this node. */
572566 int getIndirectionIndex ( ) { result = indirectionIndex }
573567
574- override Node getPreUpdateNode ( ) {
575- hasOperandAndIndex ( result , pragma [ only_bind_into ] ( fieldAddress ) .getObjectAddressOperand ( ) ,
576- indirectionIndex )
577- }
568+ override Location getLocationImpl ( ) { result = operand .getLocation ( ) }
578569
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 ( )
581574 }
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 ;
582584
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 ( ) }
584590
585591 override string toStringImpl ( ) { result = this .getPreUpdateNode ( ) + " [post update]" }
586592}
@@ -816,13 +822,8 @@ class IndirectReturnNode extends Node {
816822 * A node representing the indirection of a value after it
817823 * has been returned from a function.
818824 */
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 ;
826827
827828 int getArgumentIndex ( ) {
828829 exists ( CallInstruction call | call .getArgumentOperand ( result ) = operand )
@@ -834,12 +835,6 @@ class IndirectArgumentOutNode extends Node, TIndirectArgumentOutNode, PartialDef
834835
835836 Function getStaticCallTarget ( ) { result = this .getCallInstruction ( ) .getStaticCallTarget ( ) }
836837
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-
843838 override string toStringImpl ( ) {
844839 // This string should be unique enough to be helpful but common enough to
845840 // avoid storing too many different strings.
@@ -848,10 +843,6 @@ class IndirectArgumentOutNode extends Node, TIndirectArgumentOutNode, PartialDef
848843 not exists ( this .getStaticCallTarget ( ) ) and
849844 result = "output argument"
850845 }
851-
852- override Location getLocationImpl ( ) { result = operand .getLocation ( ) }
853-
854- override Expr getDefinedExpr ( ) { result = operand .getDef ( ) .getUnconvertedResultExpression ( ) }
855846}
856847
857848/**
0 commit comments