@@ -44,11 +44,12 @@ private newtype TIRDataFlowNode =
4444 TIndirectArgumentOutNode ( ArgumentOperand operand , int indirectionIndex ) {
4545 Ssa:: isModifiableByCall ( operand , indirectionIndex )
4646 } or
47- TRawIndirectOperand ( Operand op , int indirectionIndex ) {
48- Ssa:: hasRawIndirectOperand ( op , indirectionIndex )
47+ TRawIndirectOperand0 ( Node0Impl node , int indirectionIndex ) {
48+ Ssa:: hasRawIndirectOperand ( node . asOperand ( ) , indirectionIndex )
4949 } or
50- TRawIndirectInstruction ( Instruction instr , int indirectionIndex ) {
51- Ssa:: hasRawIndirectInstruction ( instr , indirectionIndex )
50+ TRawIndirectInstruction0 ( Node0Impl node , int indirectionIndex ) {
51+ not exists ( node .asOperand ( ) ) and
52+ Ssa:: hasRawIndirectInstruction ( node .asInstruction ( ) , indirectionIndex )
5253 } or
5354 TFinalParameterNode ( Parameter p , int indirectionIndex ) {
5455 exists ( Ssa:: FinalParameterUse use |
@@ -918,48 +919,146 @@ Type getTypeImpl(Type t, int indirectionIndex) {
918919 result instanceof UnknownType
919920}
920921
921- /**
922- * INTERNAL: Do not use.
923- *
924- * A node that represents the indirect value of an operand in the IR
925- * after `index` number of loads.
926- */
927- class RawIndirectOperand extends Node , TRawIndirectOperand {
928- Operand operand ;
929- int indirectionIndex ;
922+ private module RawIndirectNodes {
923+ /**
924+ * INTERNAL: Do not use.
925+ *
926+ * A node that represents the indirect value of an operand in the IR
927+ * after `index` number of loads.
928+ */
929+ private class RawIndirectOperand0 extends Node , TRawIndirectOperand0 {
930+ Node0Impl node ;
931+ int indirectionIndex ;
930932
931- RawIndirectOperand ( ) { this = TRawIndirectOperand ( operand , indirectionIndex ) }
933+ RawIndirectOperand0 ( ) { this = TRawIndirectOperand0 ( node , indirectionIndex ) }
932934
933- /** Gets the underlying instruction. */
934- Operand getOperand ( ) { result = operand }
935+ /** Gets the underlying instruction. */
936+ Operand getOperand ( ) { result = node . asOperand ( ) }
935937
936- /** Gets the underlying indirection index. */
937- int getIndirectionIndex ( ) { result = indirectionIndex }
938+ /** Gets the underlying indirection index. */
939+ int getIndirectionIndex ( ) { result = indirectionIndex }
938940
939- override Declaration getFunction ( ) { result = this .getOperand ( ) .getDef ( ) .getEnclosingFunction ( ) }
941+ override Declaration getFunction ( ) {
942+ result = this .getOperand ( ) .getDef ( ) .getEnclosingFunction ( )
943+ }
940944
941- override Declaration getEnclosingCallable ( ) { result = this .getFunction ( ) }
945+ override Declaration getEnclosingCallable ( ) { result = this .getFunction ( ) }
942946
943- override DataFlowType getType ( ) {
944- exists ( int sub , DataFlowType type , boolean isGLValue |
945- type = getOperandType ( operand , isGLValue ) and
946- if isGLValue = true then sub = 1 else sub = 0
947- |
948- result = getTypeImpl ( type .getUnspecifiedType ( ) , indirectionIndex - sub )
949- )
947+ override DataFlowType getType ( ) {
948+ exists ( int sub , DataFlowType type , boolean isGLValue |
949+ type = getOperandType ( this .getOperand ( ) , isGLValue ) and
950+ if isGLValue = true then sub = 1 else sub = 0
951+ |
952+ result = getTypeImpl ( type .getUnspecifiedType ( ) , indirectionIndex - sub )
953+ )
954+ }
955+
956+ final override Location getLocationImpl ( ) {
957+ if exists ( this .getOperand ( ) .getLocation ( ) )
958+ then result = this .getOperand ( ) .getLocation ( )
959+ else result instanceof UnknownDefaultLocation
960+ }
961+
962+ override string toStringImpl ( ) {
963+ result = operandNode ( this .getOperand ( ) ) .toStringImpl ( ) + " indirection"
964+ }
950965 }
951966
952- final override Location getLocationImpl ( ) {
953- if exists ( this .getOperand ( ) .getLocation ( ) )
954- then result = this .getOperand ( ) .getLocation ( )
955- else result instanceof UnknownDefaultLocation
967+ /**
968+ * INTERNAL: Do not use.
969+ *
970+ * A node that represents the indirect value of an instruction in the IR
971+ * after `index` number of loads.
972+ */
973+ private class RawIndirectInstruction0 extends Node , TRawIndirectInstruction0 {
974+ Node0Impl node ;
975+ int indirectionIndex ;
976+
977+ RawIndirectInstruction0 ( ) { this = TRawIndirectInstruction0 ( node , indirectionIndex ) }
978+
979+ /** Gets the underlying instruction. */
980+ Instruction getInstruction ( ) { result = node .asInstruction ( ) }
981+
982+ /** Gets the underlying indirection index. */
983+ int getIndirectionIndex ( ) { result = indirectionIndex }
984+
985+ override Declaration getFunction ( ) { result = this .getInstruction ( ) .getEnclosingFunction ( ) }
986+
987+ override Declaration getEnclosingCallable ( ) { result = this .getFunction ( ) }
988+
989+ override DataFlowType getType ( ) {
990+ exists ( int sub , DataFlowType type , boolean isGLValue |
991+ type = getInstructionType ( this .getInstruction ( ) , isGLValue ) and
992+ if isGLValue = true then sub = 1 else sub = 0
993+ |
994+ result = getTypeImpl ( type .getUnspecifiedType ( ) , indirectionIndex - sub )
995+ )
996+ }
997+
998+ final override Location getLocationImpl ( ) {
999+ if exists ( this .getInstruction ( ) .getLocation ( ) )
1000+ then result = this .getInstruction ( ) .getLocation ( )
1001+ else result instanceof UnknownDefaultLocation
1002+ }
1003+
1004+ override string toStringImpl ( ) {
1005+ result = instructionNode ( this .getInstruction ( ) ) .toStringImpl ( ) + " indirection"
1006+ }
9561007 }
9571008
958- override string toStringImpl ( ) {
959- result = operandNode ( this .getOperand ( ) ) .toStringImpl ( ) + " indirection"
1009+ /**
1010+ * INTERNAL: Do not use.
1011+ *
1012+ * A node that represents the indirect value of an operand in the IR
1013+ * after a number of loads.
1014+ */
1015+ class RawIndirectOperand extends Node {
1016+ int indirectionIndex ;
1017+ Operand operand ;
1018+
1019+ RawIndirectOperand ( ) {
1020+ exists ( Node0Impl node | operand = node .asOperand ( ) |
1021+ this = TRawIndirectOperand0 ( node , indirectionIndex )
1022+ or
1023+ this = TRawIndirectInstruction0 ( node , indirectionIndex )
1024+ )
1025+ }
1026+
1027+ /** Gets the operand associated with this node. */
1028+ Operand getOperand ( ) { result = operand }
1029+
1030+ /** Gets the underlying indirection index. */
1031+ int getIndirectionIndex ( ) { result = indirectionIndex }
1032+ }
1033+
1034+ /**
1035+ * INTERNAL: Do not use.
1036+ *
1037+ * A node that represents the indirect value of an instruction in the IR
1038+ * after a number of loads.
1039+ */
1040+ class RawIndirectInstruction extends Node {
1041+ int indirectionIndex ;
1042+ Instruction instr ;
1043+
1044+ RawIndirectInstruction ( ) {
1045+ exists ( Node0Impl node | instr = node .asInstruction ( ) |
1046+ this = TRawIndirectOperand0 ( node , indirectionIndex )
1047+ or
1048+ this = TRawIndirectInstruction0 ( node , indirectionIndex )
1049+ )
1050+ }
1051+
1052+ /** Gets the instruction associated with this node. */
1053+ Instruction getInstruction ( ) { result = instr }
1054+
1055+ /** Gets the underlying indirection index. */
1056+ int getIndirectionIndex ( ) { result = indirectionIndex }
9601057 }
9611058}
9621059
1060+ import RawIndirectNodes
1061+
9631062/**
9641063 * INTERNAL: do not use.
9651064 *
@@ -1021,48 +1120,6 @@ class UninitializedNode extends Node {
10211120 LocalVariable getLocalVariable ( ) { result = v }
10221121}
10231122
1024- /**
1025- * INTERNAL: Do not use.
1026- *
1027- * A node that represents the indirect value of an instruction in the IR
1028- * after `index` number of loads.
1029- */
1030- class RawIndirectInstruction extends Node , TRawIndirectInstruction {
1031- Instruction instr ;
1032- int indirectionIndex ;
1033-
1034- RawIndirectInstruction ( ) { this = TRawIndirectInstruction ( instr , indirectionIndex ) }
1035-
1036- /** Gets the underlying instruction. */
1037- Instruction getInstruction ( ) { result = instr }
1038-
1039- /** Gets the underlying indirection index. */
1040- int getIndirectionIndex ( ) { result = indirectionIndex }
1041-
1042- override Declaration getFunction ( ) { result = this .getInstruction ( ) .getEnclosingFunction ( ) }
1043-
1044- override Declaration getEnclosingCallable ( ) { result = this .getFunction ( ) }
1045-
1046- override DataFlowType getType ( ) {
1047- exists ( int sub , DataFlowType type , boolean isGLValue |
1048- type = getInstructionType ( instr , isGLValue ) and
1049- if isGLValue = true then sub = 1 else sub = 0
1050- |
1051- result = getTypeImpl ( type .getUnspecifiedType ( ) , indirectionIndex - sub )
1052- )
1053- }
1054-
1055- final override Location getLocationImpl ( ) {
1056- if exists ( this .getInstruction ( ) .getLocation ( ) )
1057- then result = this .getInstruction ( ) .getLocation ( )
1058- else result instanceof UnknownDefaultLocation
1059- }
1060-
1061- override string toStringImpl ( ) {
1062- result = instructionNode ( this .getInstruction ( ) ) .toStringImpl ( ) + " indirection"
1063- }
1064- }
1065-
10661123private module GetConvertedResultExpression {
10671124 private import semmle.code.cpp.ir.implementation.raw.internal.TranslatedExpr
10681125 private import semmle.code.cpp.ir.implementation.raw.internal.InstructionTag
@@ -1600,26 +1657,29 @@ private module Cached {
16001657 predicate localFlowStep ( Node nodeFrom , Node nodeTo ) { simpleLocalFlowStep ( nodeFrom , nodeTo ) }
16011658
16021659 private predicate indirectionOperandFlow ( RawIndirectOperand nodeFrom , Node nodeTo ) {
1603- // Reduce the indirection count by 1 if we're passing through a `LoadInstruction`.
1604- exists ( int ind , LoadInstruction load |
1605- hasOperandAndIndex ( nodeFrom , load .getSourceAddressOperand ( ) , ind ) and
1606- nodeHasInstruction ( nodeTo , load , ind - 1 )
1607- )
1608- or
1609- // If an operand flows to an instruction, then the indirection of
1610- // the operand also flows to the indirection of the instruction.
1611- exists ( Operand operand , Instruction instr , int indirectionIndex |
1612- simpleInstructionLocalFlowStep ( operand , instr ) and
1613- hasOperandAndIndex ( nodeFrom , operand , pragma [ only_bind_into ] ( indirectionIndex ) ) and
1614- hasInstructionAndIndex ( nodeTo , instr , pragma [ only_bind_into ] ( indirectionIndex ) )
1615- )
1616- or
1617- // If there's indirect flow to an operand, then there's also indirect
1618- // flow to the operand after applying some pointer arithmetic.
1619- exists ( PointerArithmeticInstruction pointerArith , int indirectionIndex |
1620- hasOperandAndIndex ( nodeFrom , pointerArith .getAnOperand ( ) ,
1621- pragma [ only_bind_into ] ( indirectionIndex ) ) and
1622- hasInstructionAndIndex ( nodeTo , pointerArith , pragma [ only_bind_into ] ( indirectionIndex ) )
1660+ nodeFrom != nodeTo and
1661+ (
1662+ // Reduce the indirection count by 1 if we're passing through a `LoadInstruction`.
1663+ exists ( int ind , LoadInstruction load |
1664+ hasOperandAndIndex ( nodeFrom , load .getSourceAddressOperand ( ) , ind ) and
1665+ nodeHasInstruction ( nodeTo , load , ind - 1 )
1666+ )
1667+ or
1668+ // If an operand flows to an instruction, then the indirection of
1669+ // the operand also flows to the indirection of the instruction.
1670+ exists ( Operand operand , Instruction instr , int indirectionIndex |
1671+ simpleInstructionLocalFlowStep ( operand , instr ) and
1672+ hasOperandAndIndex ( nodeFrom , operand , pragma [ only_bind_into ] ( indirectionIndex ) ) and
1673+ hasInstructionAndIndex ( nodeTo , instr , pragma [ only_bind_into ] ( indirectionIndex ) )
1674+ )
1675+ or
1676+ // If there's indirect flow to an operand, then there's also indirect
1677+ // flow to the operand after applying some pointer arithmetic.
1678+ exists ( PointerArithmeticInstruction pointerArith , int indirectionIndex |
1679+ hasOperandAndIndex ( nodeFrom , pointerArith .getAnOperand ( ) ,
1680+ pragma [ only_bind_into ] ( indirectionIndex ) ) and
1681+ hasInstructionAndIndex ( nodeTo , pointerArith , pragma [ only_bind_into ] ( indirectionIndex ) )
1682+ )
16231683 )
16241684 }
16251685
@@ -1645,6 +1705,7 @@ private module Cached {
16451705 private predicate indirectionInstructionFlow (
16461706 RawIndirectInstruction nodeFrom , IndirectOperand nodeTo
16471707 ) {
1708+ nodeFrom != nodeTo and
16481709 // If there's flow from an instruction to an operand, then there's also flow from the
16491710 // indirect instruction to the indirect operand.
16501711 exists ( Operand operand , Instruction instr , int indirectionIndex |
0 commit comments