@@ -44,11 +44,12 @@ private newtype TIRDataFlowNode =
44
44
TIndirectArgumentOutNode ( ArgumentOperand operand , int indirectionIndex ) {
45
45
Ssa:: isModifiableByCall ( operand , indirectionIndex )
46
46
} or
47
- TRawIndirectOperand ( Operand op , int indirectionIndex ) {
48
- Ssa:: hasRawIndirectOperand ( op , indirectionIndex )
47
+ TRawIndirectOperand0 ( Node0Impl node , int indirectionIndex ) {
48
+ Ssa:: hasRawIndirectOperand ( node . asOperand ( ) , indirectionIndex )
49
49
} 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 )
52
53
} or
53
54
TFinalParameterNode ( Parameter p , int indirectionIndex ) {
54
55
exists ( Ssa:: FinalParameterUse use |
@@ -918,48 +919,146 @@ Type getTypeImpl(Type t, int indirectionIndex) {
918
919
result instanceof UnknownType
919
920
}
920
921
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 ;
930
932
931
- RawIndirectOperand ( ) { this = TRawIndirectOperand ( operand , indirectionIndex ) }
933
+ RawIndirectOperand0 ( ) { this = TRawIndirectOperand0 ( node , indirectionIndex ) }
932
934
933
- /** Gets the underlying instruction. */
934
- Operand getOperand ( ) { result = operand }
935
+ /** Gets the underlying instruction. */
936
+ Operand getOperand ( ) { result = node . asOperand ( ) }
935
937
936
- /** Gets the underlying indirection index. */
937
- int getIndirectionIndex ( ) { result = indirectionIndex }
938
+ /** Gets the underlying indirection index. */
939
+ int getIndirectionIndex ( ) { result = indirectionIndex }
938
940
939
- override Declaration getFunction ( ) { result = this .getOperand ( ) .getDef ( ) .getEnclosingFunction ( ) }
941
+ override Declaration getFunction ( ) {
942
+ result = this .getOperand ( ) .getDef ( ) .getEnclosingFunction ( )
943
+ }
940
944
941
- override Declaration getEnclosingCallable ( ) { result = this .getFunction ( ) }
945
+ override Declaration getEnclosingCallable ( ) { result = this .getFunction ( ) }
942
946
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
+ }
950
965
}
951
966
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
+ }
956
1007
}
957
1008
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 }
960
1057
}
961
1058
}
962
1059
1060
+ import RawIndirectNodes
1061
+
963
1062
/**
964
1063
* INTERNAL: do not use.
965
1064
*
@@ -1021,48 +1120,6 @@ class UninitializedNode extends Node {
1021
1120
LocalVariable getLocalVariable ( ) { result = v }
1022
1121
}
1023
1122
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
-
1066
1123
private module GetConvertedResultExpression {
1067
1124
private import semmle.code.cpp.ir.implementation.raw.internal.TranslatedExpr
1068
1125
private import semmle.code.cpp.ir.implementation.raw.internal.InstructionTag
@@ -1600,26 +1657,29 @@ private module Cached {
1600
1657
predicate localFlowStep ( Node nodeFrom , Node nodeTo ) { simpleLocalFlowStep ( nodeFrom , nodeTo ) }
1601
1658
1602
1659
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
+ )
1623
1683
)
1624
1684
}
1625
1685
@@ -1645,6 +1705,7 @@ private module Cached {
1645
1705
private predicate indirectionInstructionFlow (
1646
1706
RawIndirectInstruction nodeFrom , IndirectOperand nodeTo
1647
1707
) {
1708
+ nodeFrom != nodeTo and
1648
1709
// If there's flow from an instruction to an operand, then there's also flow from the
1649
1710
// indirect instruction to the indirect operand.
1650
1711
exists ( Operand operand , Instruction instr , int indirectionIndex |
0 commit comments