Skip to content

Commit 1a458aa

Browse files
author
Robert Marsh
committed
C++: IR dataflow edges through outparams
1 parent 46c414b commit 1a458aa

7 files changed

Lines changed: 88 additions & 37 deletions

File tree

cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowPrivate.qll

Lines changed: 68 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -24,40 +24,101 @@ class ArgumentNode extends Node {
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
*/
3335
class 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() {
48+
this = TIndirectReturnKind(index)
49+
}
50+
51+
override string toString() { result = "outparam[" + index.toString() +"]" }
3652
}
3753

3854
/** A data flow node that occurs as the result of a `ReturnStmt`. */
3955
class ReturnNode extends Node {
40-
ReturnNode() { exists(ReturnValueInstruction ret | this.asInstruction() = ret.getReturnValue()) }
56+
Instruction primary;
57+
ReturnNode() {
58+
exists(ReturnValueInstruction ret | this.asInstruction() = ret.getReturnValue() and primary = ret)
59+
or
60+
exists(ReturnIndirectionInstruction rii | this.asInstruction() = rii.getSideEffectOperand().getAnyDef() and primary = rii)
61+
}
4162

4263
/** Gets the kind of this returned value. */
43-
ReturnKind getKind() { result = TNormalReturnKind() }
64+
abstract ReturnKind getKind();
65+
}
66+
67+
class ReturnValueNode extends ReturnNode {
68+
override ReturnValueInstruction primary;
69+
70+
override ReturnKind getKind() { result = TNormalReturnKind() }
71+
}
72+
73+
class ReturnIndirectionNode extends ReturnNode {
74+
override ReturnIndirectionInstruction primary;
75+
76+
override ReturnKind getKind() { result = TIndirectReturnKind(primary.getParameter().getIndex()) }
4477
}
4578

4679
/** A data flow node that represents the output of a call. */
4780
class OutNode extends Node {
48-
override CallInstruction instr;
81+
OutNode() {
82+
instr instanceof CallInstruction or
83+
instr instanceof WriteSideEffectInstruction
84+
}
4985

5086
/** Gets the underlying call. */
51-
DataFlowCall getCall() { result = instr }
87+
abstract DataFlowCall getCall();
88+
89+
abstract ReturnKind getReturnKind();
5290
}
5391

92+
private class CallOutNode extends OutNode {
93+
override CallInstruction instr;
94+
95+
override DataFlowCall getCall() {
96+
result = instr
97+
}
98+
99+
override ReturnKind getReturnKind() {
100+
result instanceof NormalReturnKind
101+
}
102+
}
103+
104+
private class SideEffectOutNode extends OutNode {
105+
override WriteSideEffectInstruction instr;
106+
107+
override DataFlowCall getCall() {
108+
result = instr.getPrimaryInstruction()
109+
}
110+
111+
override ReturnKind getReturnKind() {
112+
result = TIndirectReturnKind(instr.getIndex())
113+
}
114+
}
54115
/**
55116
* Gets a node that can read the value returned from `call` with return kind
56117
* `kind`.
57118
*/
58119
OutNode getAnOutNode(DataFlowCall call, ReturnKind kind) {
59120
result.getCall() = call and
60-
kind = TNormalReturnKind()
121+
result.getReturnKind() = kind
61122
}
62123

63124
/**

cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/Instruction.qll

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -743,7 +743,7 @@ class ReturnValueInstruction extends ReturnInstruction {
743743
final Instruction getReturnValue() { result = getReturnValueOperand().getDef() }
744744
}
745745

746-
class ReturnIndirectionInstruction extends Instruction {
746+
class ReturnIndirectionInstruction extends VariableInstruction {
747747
ReturnIndirectionInstruction() { getOpcode() instanceof Opcode::ReturnIndirection }
748748

749749
final SideEffectOperand getSideEffectOperand() { result = getAnOperand() }
@@ -753,6 +753,8 @@ class ReturnIndirectionInstruction extends Instruction {
753753
final AddressOperand getSourceAddressOperand() { result = getAnOperand() }
754754

755755
final Instruction getSourceAddress() { result = getSourceAddressOperand().getDef() }
756+
757+
final Language::Parameter getParameter() { result = var.(IRUserVariable).getVariable() }
756758
}
757759

758760
class CopyInstruction extends Instruction {
@@ -1237,11 +1239,6 @@ class IndirectReadSideEffectInstruction extends ReadSideEffectInstruction {
12371239
/**
12381240
* An instruction representing the read of an indirect buffer parameter within a function call.
12391241
*/
1240-
class BufferReadSideEffectInstruction extends ReadSideEffectInstruction {
1241-
BufferReadSideEffectInstruction() { getOpcode() instanceof Opcode::BufferReadSideEffect }
1242-
}
1243-
1244-
/**
12451242
* An instruction representing the read of an indirect buffer parameter within a function call.
12461243
*/
12471244
class SizedBufferReadSideEffectInstruction extends ReadSideEffectInstruction {

cpp/ql/src/semmle/code/cpp/ir/implementation/raw/Instruction.qll

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -743,7 +743,7 @@ class ReturnValueInstruction extends ReturnInstruction {
743743
final Instruction getReturnValue() { result = getReturnValueOperand().getDef() }
744744
}
745745

746-
class ReturnIndirectionInstruction extends Instruction {
746+
class ReturnIndirectionInstruction extends VariableInstruction {
747747
ReturnIndirectionInstruction() { getOpcode() instanceof Opcode::ReturnIndirection }
748748

749749
final SideEffectOperand getSideEffectOperand() { result = getAnOperand() }
@@ -753,6 +753,8 @@ class ReturnIndirectionInstruction extends Instruction {
753753
final AddressOperand getSourceAddressOperand() { result = getAnOperand() }
754754

755755
final Instruction getSourceAddress() { result = getSourceAddressOperand().getDef() }
756+
757+
final Language::Parameter getParameter() { result = var.(IRUserVariable).getVariable() }
756758
}
757759

758760
class CopyInstruction extends Instruction {
@@ -1237,11 +1239,6 @@ class IndirectReadSideEffectInstruction extends ReadSideEffectInstruction {
12371239
/**
12381240
* An instruction representing the read of an indirect buffer parameter within a function call.
12391241
*/
1240-
class BufferReadSideEffectInstruction extends ReadSideEffectInstruction {
1241-
BufferReadSideEffectInstruction() { getOpcode() instanceof Opcode::BufferReadSideEffect }
1242-
}
1243-
1244-
/**
12451242
* An instruction representing the read of an indirect buffer parameter within a function call.
12461243
*/
12471244
class SizedBufferReadSideEffectInstruction extends ReadSideEffectInstruction {

cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/TranslatedFunction.qll

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -628,4 +628,9 @@ class TranslatedReadEffect extends TranslatedElement, TTranslatedReadEffect {
628628
operandTag = sideEffectOperand() and
629629
result = getUnknownType()
630630
}
631+
632+
final override IRVariable getInstructionVariable(InstructionTag tag) {
633+
tag = OnlyInstructionTag() and
634+
result = getIRUserVariable(getFunction(), param)
635+
}
631636
}

cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/Instruction.qll

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -743,7 +743,7 @@ class ReturnValueInstruction extends ReturnInstruction {
743743
final Instruction getReturnValue() { result = getReturnValueOperand().getDef() }
744744
}
745745

746-
class ReturnIndirectionInstruction extends Instruction {
746+
class ReturnIndirectionInstruction extends VariableInstruction {
747747
ReturnIndirectionInstruction() { getOpcode() instanceof Opcode::ReturnIndirection }
748748

749749
final SideEffectOperand getSideEffectOperand() { result = getAnOperand() }
@@ -753,6 +753,8 @@ class ReturnIndirectionInstruction extends Instruction {
753753
final AddressOperand getSourceAddressOperand() { result = getAnOperand() }
754754

755755
final Instruction getSourceAddress() { result = getSourceAddressOperand().getDef() }
756+
757+
final Language::Parameter getParameter() { result = var.(IRUserVariable).getVariable() }
756758
}
757759

758760
class CopyInstruction extends Instruction {
@@ -1237,11 +1239,6 @@ class IndirectReadSideEffectInstruction extends ReadSideEffectInstruction {
12371239
/**
12381240
* An instruction representing the read of an indirect buffer parameter within a function call.
12391241
*/
1240-
class BufferReadSideEffectInstruction extends ReadSideEffectInstruction {
1241-
BufferReadSideEffectInstruction() { getOpcode() instanceof Opcode::BufferReadSideEffect }
1242-
}
1243-
1244-
/**
12451242
* An instruction representing the read of an indirect buffer parameter within a function call.
12461243
*/
12471244
class SizedBufferReadSideEffectInstruction extends ReadSideEffectInstruction {

csharp/ql/src/semmle/code/csharp/ir/implementation/raw/Instruction.qll

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -743,7 +743,7 @@ class ReturnValueInstruction extends ReturnInstruction {
743743
final Instruction getReturnValue() { result = getReturnValueOperand().getDef() }
744744
}
745745

746-
class ReturnIndirectionInstruction extends Instruction {
746+
class ReturnIndirectionInstruction extends VariableInstruction {
747747
ReturnIndirectionInstruction() { getOpcode() instanceof Opcode::ReturnIndirection }
748748

749749
final SideEffectOperand getSideEffectOperand() { result = getAnOperand() }
@@ -753,6 +753,8 @@ class ReturnIndirectionInstruction extends Instruction {
753753
final AddressOperand getSourceAddressOperand() { result = getAnOperand() }
754754

755755
final Instruction getSourceAddress() { result = getSourceAddressOperand().getDef() }
756+
757+
final Language::Parameter getParameter() { result = var.(IRUserVariable).getVariable() }
756758
}
757759

758760
class CopyInstruction extends Instruction {
@@ -1237,11 +1239,6 @@ class IndirectReadSideEffectInstruction extends ReadSideEffectInstruction {
12371239
/**
12381240
* An instruction representing the read of an indirect buffer parameter within a function call.
12391241
*/
1240-
class BufferReadSideEffectInstruction extends ReadSideEffectInstruction {
1241-
BufferReadSideEffectInstruction() { getOpcode() instanceof Opcode::BufferReadSideEffect }
1242-
}
1243-
1244-
/**
12451242
* An instruction representing the read of an indirect buffer parameter within a function call.
12461243
*/
12471244
class SizedBufferReadSideEffectInstruction extends ReadSideEffectInstruction {

csharp/ql/src/semmle/code/csharp/ir/implementation/unaliased_ssa/Instruction.qll

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -743,7 +743,7 @@ class ReturnValueInstruction extends ReturnInstruction {
743743
final Instruction getReturnValue() { result = getReturnValueOperand().getDef() }
744744
}
745745

746-
class ReturnIndirectionInstruction extends Instruction {
746+
class ReturnIndirectionInstruction extends VariableInstruction {
747747
ReturnIndirectionInstruction() { getOpcode() instanceof Opcode::ReturnIndirection }
748748

749749
final SideEffectOperand getSideEffectOperand() { result = getAnOperand() }
@@ -753,6 +753,8 @@ class ReturnIndirectionInstruction extends Instruction {
753753
final AddressOperand getSourceAddressOperand() { result = getAnOperand() }
754754

755755
final Instruction getSourceAddress() { result = getSourceAddressOperand().getDef() }
756+
757+
final Language::Parameter getParameter() { result = var.(IRUserVariable).getVariable() }
756758
}
757759

758760
class CopyInstruction extends Instruction {
@@ -1237,11 +1239,6 @@ class IndirectReadSideEffectInstruction extends ReadSideEffectInstruction {
12371239
/**
12381240
* An instruction representing the read of an indirect buffer parameter within a function call.
12391241
*/
1240-
class BufferReadSideEffectInstruction extends ReadSideEffectInstruction {
1241-
BufferReadSideEffectInstruction() { getOpcode() instanceof Opcode::BufferReadSideEffect }
1242-
}
1243-
1244-
/**
12451242
* An instruction representing the read of an indirect buffer parameter within a function call.
12461243
*/
12471244
class SizedBufferReadSideEffectInstruction extends ReadSideEffectInstruction {

0 commit comments

Comments
 (0)