@@ -6,6 +6,86 @@ private import DataFlowImplConsistency
66private import semmle.code.cpp.ir.internal.IRCppLanguage
77private import SsaInternals as Ssa
88
9+ /**
10+ * INTERNAL: Do not use.
11+ *
12+ * A node that represents the indirect value of an operand in the IR
13+ * after `index` number of loads.
14+ *
15+ * Note: Unlike `RawIndirectOperand`, a value of type `IndirectOperand` may
16+ * be an `OperandNode`.
17+ */
18+ class IndirectOperand extends Node {
19+ Operand operand ;
20+ int indirectionIndex ;
21+
22+ IndirectOperand ( ) {
23+ this .( RawIndirectOperand ) .getOperand ( ) = operand and
24+ this .( RawIndirectOperand ) .getIndirectionIndex ( ) = indirectionIndex
25+ or
26+ this .( OperandNode ) .getOperand ( ) =
27+ Ssa:: getIRRepresentationOfIndirectOperand ( operand , indirectionIndex )
28+ }
29+
30+ /** Gets the underlying operand. */
31+ Operand getOperand ( ) { result = operand }
32+
33+ /** Gets the underlying indirection index. */
34+ int getIndirectionIndex ( ) { result = indirectionIndex }
35+
36+ /**
37+ * Holds if this `IndirectOperand` is represented directly in the IR instead of
38+ * a `RawIndirectionOperand` with operand `op` and indirection index `index`.
39+ */
40+ predicate isIRRepresentationOf ( Operand op , int index ) {
41+ this instanceof OperandNode and
42+ (
43+ op = operand and
44+ index = indirectionIndex
45+ )
46+ }
47+ }
48+
49+ /**
50+ * INTERNAL: Do not use.
51+ *
52+ * A node that represents the indirect value of an instruction in the IR
53+ * after `index` number of loads.
54+ *
55+ * Note: Unlike `RawIndirectInstruction`, a value of type `IndirectInstruction` may
56+ * be an `InstructionNode`.
57+ */
58+ class IndirectInstruction extends Node {
59+ Instruction instr ;
60+ int indirectionIndex ;
61+
62+ IndirectInstruction ( ) {
63+ this .( RawIndirectInstruction ) .getInstruction ( ) = instr and
64+ this .( RawIndirectInstruction ) .getIndirectionIndex ( ) = indirectionIndex
65+ or
66+ this .( InstructionNode ) .getInstruction ( ) =
67+ Ssa:: getIRRepresentationOfIndirectInstruction ( instr , indirectionIndex )
68+ }
69+
70+ /** Gets the underlying instruction. */
71+ Instruction getInstruction ( ) { result = instr }
72+
73+ /** Gets the underlying indirection index. */
74+ int getIndirectionIndex ( ) { result = indirectionIndex }
75+
76+ /**
77+ * Holds if this `IndirectInstruction` is represented directly in the IR instead of
78+ * a `RawIndirectionInstruction` with instruction `i` and indirection index `index`.
79+ */
80+ predicate isIRRepresentationOf ( Instruction i , int index ) {
81+ this instanceof InstructionNode and
82+ (
83+ i = instr and
84+ index = indirectionIndex
85+ )
86+ }
87+ }
88+
989/** Gets the callable in which this node occurs. */
1090DataFlowCallable nodeGetEnclosingCallable ( Node n ) { result = n .getEnclosingCallable ( ) }
1191
@@ -47,24 +127,6 @@ private class PrimaryArgumentNode extends ArgumentNode, OperandNode {
47127 override predicate argumentOf ( DataFlowCall call , ArgumentPosition pos ) {
48128 op = call .getArgumentOperand ( pos .( DirectPosition ) .getIndex ( ) )
49129 }
50-
51- override string toStringImpl ( ) { result = argumentOperandToString ( op ) }
52- }
53-
54- private string argumentOperandToString ( ArgumentOperand op ) {
55- exists ( Expr unconverted |
56- unconverted = op .getDef ( ) .getUnconvertedResultExpression ( ) and
57- result = unconverted .toString ( )
58- )
59- or
60- // Certain instructions don't map to an unconverted result expression. For these cases
61- // we fall back to a simpler naming scheme. This can happen in IR-generated constructors.
62- not exists ( op .getDef ( ) .getUnconvertedResultExpression ( ) ) and
63- (
64- result = "Argument " + op .( PositionalArgumentOperand ) .getIndex ( )
65- or
66- op instanceof ThisArgumentOperand and result = "Argument this"
67- )
68130}
69131
70132private class SideEffectArgumentNode extends ArgumentNode , SideEffectOperandNode {
@@ -73,10 +135,6 @@ private class SideEffectArgumentNode extends ArgumentNode, SideEffectOperandNode
73135 pos .( IndirectionPosition ) .getArgumentIndex ( ) = this .getArgumentIndex ( ) and
74136 pos .( IndirectionPosition ) .getIndirectionIndex ( ) = super .getIndirectionIndex ( )
75137 }
76-
77- override string toStringImpl ( ) {
78- result = argumentOperandToString ( this .getAddressOperand ( ) ) + " indirection"
79- }
80138}
81139
82140/** A parameter position represented by an integer. */
@@ -200,15 +258,21 @@ private predicate hasNonInitializeParameterDef(IRVariable v) {
200258
201259class ReturnIndirectionNode extends IndirectReturnNode , ReturnNode {
202260 override ReturnKind getKind ( ) {
203- exists ( int argumentIndex , ReturnIndirectionInstruction returnInd |
204- returnInd .hasIndex ( argumentIndex ) and
205- this .getAddressOperand ( ) = returnInd .getSourceAddressOperand ( ) and
206- result = TIndirectReturnKind ( argumentIndex , this .getIndirectionIndex ( ) ) and
207- hasNonInitializeParameterDef ( returnInd .getIRVariable ( ) )
261+ exists ( Operand op , int i |
262+ hasOperandAndIndex ( this , pragma [ only_bind_into ] ( op ) , pragma [ only_bind_into ] ( i ) )
263+ |
264+ exists ( int argumentIndex , ReturnIndirectionInstruction returnInd |
265+ op = returnInd .getSourceAddressOperand ( ) and
266+ returnInd .hasIndex ( argumentIndex ) and
267+ hasNonInitializeParameterDef ( returnInd .getIRVariable ( ) ) and
268+ result = TIndirectReturnKind ( argumentIndex , pragma [ only_bind_into ] ( i ) )
269+ )
270+ or
271+ exists ( ReturnValueInstruction return |
272+ op = return .getReturnAddressOperand ( ) and
273+ result = TNormalReturnKind ( i - 1 )
274+ )
208275 )
209- or
210- this .getAddressOperand ( ) = any ( ReturnValueInstruction r ) .getReturnAddressOperand ( ) and
211- result = TNormalReturnKind ( this .getIndirectionIndex ( ) - 1 )
212276 }
213277}
214278
0 commit comments