@@ -24,31 +24,86 @@ class ArgumentNode extends InstructionNode {
2424 DataFlowCall getCall ( ) { this .argumentOf ( result , _) }
2525}
2626
27- private newtype TReturnKind = TNormalReturnKind ( )
27+ private newtype TReturnKind =
28+ TNormalReturnKind ( ) or
29+ TIndirectReturnKind ( ParameterIndex index )
2830
2931/**
3032 * A return kind. A return kind describes how a value can be returned
3133 * from a callable. For C++, this is simply a function return.
3234 */
3335class ReturnKind extends TReturnKind {
3436 /** Gets a textual representation of this return kind. */
35- string toString ( ) { result = "return" }
37+ abstract string toString ( ) ;
38+ }
39+
40+ private class NormalReturnKind extends ReturnKind , TNormalReturnKind {
41+ override string toString ( ) { result = "return" }
42+ }
43+
44+ private class IndirectReturnKind extends ReturnKind , TIndirectReturnKind {
45+ ParameterIndex index ;
46+
47+ IndirectReturnKind ( ) { this = TIndirectReturnKind ( index ) }
48+
49+ override string toString ( ) { result = "outparam[" + index .toString ( ) + "]" }
3650}
3751
3852/** A data flow node that occurs as the result of a `ReturnStmt`. */
3953class ReturnNode extends InstructionNode {
40- ReturnNode ( ) { exists ( ReturnValueInstruction ret | this .getInstruction ( ) = ret .getReturnValue ( ) ) }
54+ Instruction primary ;
55+
56+ ReturnNode ( ) {
57+ exists ( ReturnValueInstruction ret | instr = ret .getReturnValue ( ) and primary = ret )
58+ or
59+ exists ( ReturnIndirectionInstruction rii |
60+ instr = rii .getSideEffectOperand ( ) .getAnyDef ( ) and primary = rii
61+ )
62+ }
4163
4264 /** Gets the kind of this returned value. */
43- ReturnKind getKind ( ) { result = TNormalReturnKind ( ) }
65+ abstract ReturnKind getKind ( ) ;
66+ }
67+
68+ class ReturnValueNode extends ReturnNode {
69+ override ReturnValueInstruction primary ;
70+
71+ override ReturnKind getKind ( ) { result = TNormalReturnKind ( ) }
72+ }
73+
74+ class ReturnIndirectionNode extends ReturnNode {
75+ override ReturnIndirectionInstruction primary ;
76+
77+ override ReturnKind getKind ( ) { result = TIndirectReturnKind ( primary .getParameter ( ) .getIndex ( ) ) }
4478}
4579
4680/** A data flow node that represents the output of a call. */
4781class OutNode extends InstructionNode {
48- override CallInstruction instr ;
82+ OutNode ( ) {
83+ instr instanceof CallInstruction or
84+ instr instanceof WriteSideEffectInstruction
85+ }
4986
5087 /** Gets the underlying call. */
51- DataFlowCall getCall ( ) { result = instr }
88+ abstract DataFlowCall getCall ( ) ;
89+
90+ abstract ReturnKind getReturnKind ( ) ;
91+ }
92+
93+ private class CallOutNode extends OutNode {
94+ override CallInstruction instr ;
95+
96+ override DataFlowCall getCall ( ) { result = instr }
97+
98+ override ReturnKind getReturnKind ( ) { result instanceof NormalReturnKind }
99+ }
100+
101+ private class SideEffectOutNode extends OutNode {
102+ override WriteSideEffectInstruction instr ;
103+
104+ override DataFlowCall getCall ( ) { result = instr .getPrimaryInstruction ( ) }
105+
106+ override ReturnKind getReturnKind ( ) { result = TIndirectReturnKind ( instr .getIndex ( ) ) }
52107}
53108
54109/**
@@ -57,7 +112,7 @@ class OutNode extends InstructionNode {
57112 */
58113OutNode getAnOutNode ( DataFlowCall call , ReturnKind kind ) {
59114 result .getCall ( ) = call and
60- kind = TNormalReturnKind ( )
115+ result . getReturnKind ( ) = kind
61116}
62117
63118/**
0 commit comments