Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 1ace9ee

Browse files
committed
C++: Create a proper class for DataFlowCallable, that includes summarized callables.
1 parent e1a5a84 commit 1ace9ee

5 files changed

Lines changed: 99 additions & 52 deletions

File tree

cpp/ql/lib/semmle/code/cpp/dataflow/internal/FlowSummaryImpl.qll

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,10 @@ module SourceSinkInterpretationInput implements
119119
}
120120

121121
/** Gets the callable that this node corresponds to, if any. */
122-
DataFlowCallable asCallable() { result.(Function) = this.asElement() }
122+
DataFlowCallable asCallable() {
123+
result.asSourceCallable() = this.asElement()
124+
// TODO: or summary callable?
125+
}
123126

124127
/** Gets the target of this call, if any. */
125128
Element getCallTarget() { result = this.asCall().getStaticCallTarget() }

cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowDispatch.qll

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ private import DataFlowImplCommon as DataFlowImplCommon
1414
cached
1515
DataFlowCallable defaultViableCallable(DataFlowCall call) {
1616
DataFlowImplCommon::forceCachingInSameStage() and
17-
result = call.getStaticCallTarget()
17+
result = TSourceCallable(call.getStaticCallTarget())
1818
or
1919
// If the target of the call does not have a body in the snapshot, it might
2020
// be because the target is just a header declaration, and the real target
@@ -24,12 +24,12 @@ DataFlowCallable defaultViableCallable(DataFlowCall call) {
2424
// that as a potential callee.
2525
exists(string qualifiedName, int nparams |
2626
callSignatureWithoutBody(qualifiedName, nparams, call.asCallInstruction()) and
27-
functionSignatureWithBody(qualifiedName, nparams, result) and
27+
functionSignatureWithBody(qualifiedName, nparams, result.asSourceCallable()) and
2828
strictcount(Function other | functionSignatureWithBody(qualifiedName, nparams, other)) = 1
2929
)
3030
or
3131
// Virtual dispatch
32-
result = call.(VirtualDispatch::DataSensitiveCall).resolve()
32+
result = TSourceCallable(call.(VirtualDispatch::DataSensitiveCall).resolve())
3333
}
3434

3535
/**
@@ -89,7 +89,7 @@ private module VirtualDispatch {
8989
// Call return
9090
exists(DataFlowCall call, ReturnKind returnKind |
9191
other = getAnOutNode(call, returnKind) and
92-
returnNodeWithKindAndEnclosingCallable(src, returnKind, call.getStaticCallTarget())
92+
returnNodeWithKindAndEnclosingCallable(src, returnKind, TSourceCallable(call.getStaticCallTarget()))
9393
) and
9494
allowFromArg = false
9595
or
@@ -258,12 +258,12 @@ predicate mayBenefitFromCallContext(DataFlowCall call, DataFlowCallable f) {
258258
* value is given as the `arg`'th argument to `f`.
259259
*/
260260
private predicate mayBenefitFromCallContext(
261-
VirtualDispatch::DataSensitiveCall call, Function f, int arg
261+
VirtualDispatch::DataSensitiveCall call, DataFlowCallable f, int arg
262262
) {
263263
f = pragma[only_bind_out](call).getEnclosingCallable() and
264264
exists(InitializeParameterInstruction init |
265265
not exists(call.getStaticCallTarget()) and
266-
init.getEnclosingFunction() = f and
266+
init.getEnclosingFunction() = f.asSourceCallable() and
267267
call.flowsFrom(DataFlow::instructionNode(init), _) and
268268
init.getParameter().getIndex() = arg
269269
)
@@ -275,10 +275,10 @@ private predicate mayBenefitFromCallContext(
275275
*/
276276
DataFlowCallable viableImplInCallContext(DataFlowCall call, DataFlowCall ctx) {
277277
result = viableCallable(call) and
278-
exists(int i, Function f |
278+
exists(int i, DataFlowCallable f |
279279
mayBenefitFromCallContext(pragma[only_bind_into](call), f, i) and
280-
f = ctx.getStaticCallTarget() and
281-
result = ctx.getArgument(i).getUnconvertedResultExpression().(FunctionAccess).getTarget()
280+
f.asSourceCallable() = ctx.getStaticCallTarget() and
281+
result = TSourceCallable(ctx.getArgument(i).getUnconvertedResultExpression().(FunctionAccess).getTarget())
282282
)
283283
}
284284

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

Lines changed: 56 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ class Node0Impl extends TIRDataFlowNode0 {
104104
/**
105105
* INTERNAL: Do not use.
106106
*/
107-
Declaration getEnclosingCallable() { none() } // overridden in subclasses
107+
DataFlowCallable getEnclosingCallable() { none() } // overridden in subclasses
108108

109109
/** Gets the function to which this node belongs, if any. */
110110
Declaration getFunction() { none() } // overridden in subclasses
@@ -174,7 +174,7 @@ abstract class InstructionNode0 extends Node0Impl {
174174
/** Gets the instruction corresponding to this node. */
175175
Instruction getInstruction() { result = instr }
176176

177-
override Declaration getEnclosingCallable() { result = this.getFunction() }
177+
override DataFlowCallable getEnclosingCallable() { result = TSourceCallable(this.getFunction()) }
178178

179179
override Declaration getFunction() { result = instr.getEnclosingFunction() }
180180

@@ -219,7 +219,7 @@ abstract class OperandNode0 extends Node0Impl {
219219
/** Gets the operand corresponding to this node. */
220220
Operand getOperand() { result = op }
221221

222-
override Declaration getEnclosingCallable() { result = this.getFunction() }
222+
override DataFlowCallable getEnclosingCallable() { result = TSourceCallable(this.getFunction()) }
223223

224224
override Declaration getFunction() { result = op.getUse().getEnclosingFunction() }
225225

@@ -340,7 +340,7 @@ DataFlowCallable nodeGetEnclosingCallable(Node n) { result = n.getEnclosingCalla
340340

341341
/** Holds if `p` is a `ParameterNode` of `c` with position `pos`. */
342342
predicate isParameterNode(ParameterNode p, DataFlowCallable c, ParameterPosition pos) {
343-
p.isParameterOf(c, pos)
343+
p.isParameterOf(c.asSourceCallable(), pos) // TODO: if c is a summary node?
344344
}
345345

346346
/** Holds if `arg` is an `ArgumentNode` of `c` with position `pos`. */
@@ -941,13 +941,57 @@ class CastNode extends Node {
941941
CastNode() { none() } // stub implementation
942942
}
943943

944+
cached
945+
newtype TDataFlowCallable =
946+
TSourceCallable(Cpp::Declaration decl) { not decl instanceof FlowSummaryImpl::Public::SummarizedCallable } or
947+
TSummarizedCallable(FlowSummaryImpl::Public::SummarizedCallable c)
948+
944949
/**
945-
* A function that may contain code or a variable that may contain itself. When
946-
* flow crosses from one _enclosing callable_ to another, the interprocedural
947-
* data-flow library discards call contexts and inserts a node in the big-step
948-
* relation used for human-readable path explanations.
950+
* A callable, which may be:
951+
* - a function (that may contain code)
952+
* - a summarized function (that may contain only `FlowSummaryNode`s)
953+
* - a variable (this is used as context for global initialization, and also
954+
* for the mid-point in interprocedural data flow between a write and read
955+
* of a global variable in different functions).
956+
* When flow crosses from one _enclosing callable_ to another, the
957+
* interprocedural data-flow library discards call contexts and inserts a node
958+
* in the big-step relation used for human-readable path explanations.
949959
*/
950-
class DataFlowCallable = Cpp::Declaration;
960+
class DataFlowCallable extends TDataFlowCallable {
961+
/** Gets the location of this callable. */
962+
Location getLocation() { none() }
963+
964+
/** Gets a textual representation of this callable. */
965+
string toString() { none() }
966+
967+
Cpp::Declaration asSourceCallable() { this = TSourceCallable(result) }
968+
969+
FlowSummaryImpl::Public::SummarizedCallable asSummarizedCallable() { this = TSummarizedCallable(result) }
970+
971+
/* Callable::TypeRange getUnderlyingCallable() { TODO
972+
result = this.asSummarizedCallable() or result = this.asSourceCallable()
973+
}*/
974+
}
975+
976+
private class SourceCallable extends DataFlowCallable, TSourceCallable {
977+
Cpp::Declaration decl;
978+
979+
SourceCallable() { this = TSourceCallable(decl) }
980+
981+
override string toString() { result = decl.toString() }
982+
983+
override Location getLocation() { result = decl.getLocation() }
984+
}
985+
986+
private class SummarizedCallable extends DataFlowCallable, TSummarizedCallable {
987+
FlowSummaryImpl::Public::SummarizedCallable sc;
988+
989+
SummarizedCallable() { this = TSummarizedCallable(sc) }
990+
991+
override string toString() { result = sc.toString() }
992+
993+
override Location getLocation() { result = sc.getLocation() }
994+
}
951995

952996
class DataFlowExpr = Expr;
953997

@@ -980,7 +1024,7 @@ class DataFlowCall extends TDataFlowCall {
9801024
/**
9811025
* Gets the `Function` that the call targets, if this is statically known.
9821026
*/
983-
Function getStaticCallTarget() { none() }
1027+
Function getStaticCallTarget() { none() } // TODO: should this return DataFlowCallable?
9841028

9851029
/**
9861030
* Gets the `index`'th argument operand. The qualifier is considered to have index `-1`.
@@ -1029,7 +1073,7 @@ private class NormalCall extends DataFlowCall, TNormalCall {
10291073
result = call.getArgumentOperand(index)
10301074
}
10311075

1032-
override DataFlowCallable getEnclosingCallable() { result = call.getEnclosingFunction() }
1076+
override DataFlowCallable getEnclosingCallable() { result = TSourceCallable(call.getEnclosingFunction()) }
10331077

10341078
override string toString() { result = call.toString() }
10351079

@@ -1053,7 +1097,7 @@ class SummaryCall extends DataFlowCall, TSummaryCall {
10531097

10541098
// override ArgumentOperand getArgumentOperand(int index) TODO
10551099

1056-
// override DataFlowCallable getEnclosingCallable() { result = TSummarizedCallable(c) } TODO
1100+
override DataFlowCallable getEnclosingCallable() { result = TSummarizedCallable(c) }
10571101

10581102
override string toString() { result = "[summary] call to " + receiver + " in " + c }
10591103

cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowUtil.qll

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ class Node extends TIRDataFlowNode {
150150
/**
151151
* INTERNAL: Do not use.
152152
*/
153-
Declaration getEnclosingCallable() { none() } // overridden in subclasses
153+
DataFlowCallable getEnclosingCallable() { none() } // overridden in subclasses
154154

155155
/** Gets the function to which this node belongs, if any. */
156156
Declaration getFunction() { none() } // overridden in subclasses
@@ -503,7 +503,7 @@ private class Node0 extends Node, TNode0 {
503503

504504
Node0() { this = TNode0(node) }
505505

506-
override Declaration getEnclosingCallable() { result = node.getEnclosingCallable() }
506+
override DataFlowCallable getEnclosingCallable() { result = node.getEnclosingCallable() }
507507

508508
override Declaration getFunction() { result = node.getFunction() }
509509

@@ -568,7 +568,7 @@ class PostUpdateNodeImpl extends PartialDefinitionNode, TPostUpdateNodeImpl {
568568

569569
override Declaration getFunction() { result = operand.getUse().getEnclosingFunction() }
570570

571-
override Declaration getEnclosingCallable() { result = this.getFunction() }
571+
override DataFlowCallable getEnclosingCallable() { result = TSourceCallable(this.getFunction()) }
572572

573573
/** Gets the operand associated with this node. */
574574
Operand getOperand() { result = operand }
@@ -621,7 +621,7 @@ class SsaPhiNode extends Node, TSsaPhiNode {
621621
/** Gets the phi node associated with this node. */
622622
Ssa::PhiNode getPhiNode() { result = phi }
623623

624-
override Declaration getEnclosingCallable() { result = this.getFunction() }
624+
override DataFlowCallable getEnclosingCallable() { result = TSourceCallable(this.getFunction()) }
625625

626626
override Declaration getFunction() { result = phi.getBasicBlock().getEnclosingFunction() }
627627

@@ -690,7 +690,7 @@ class SideEffectOperandNode extends Node instanceof IndirectOperand {
690690

691691
int getArgumentIndex() { result = argumentIndex }
692692

693-
override Declaration getEnclosingCallable() { result = this.getFunction() }
693+
override DataFlowCallable getEnclosingCallable() { result = TSourceCallable(this.getFunction()) }
694694

695695
override Declaration getFunction() { result = call.getEnclosingFunction() }
696696

@@ -711,7 +711,7 @@ class FinalGlobalValue extends Node, TFinalGlobalValue {
711711
/** Gets the underlying SSA use. */
712712
Ssa::GlobalUse getGlobalUse() { result = globalUse }
713713

714-
override Declaration getEnclosingCallable() { result = this.getFunction() }
714+
override DataFlowCallable getEnclosingCallable() { result = TSourceCallable(this.getFunction()) }
715715

716716
override Declaration getFunction() { result = globalUse.getIRFunction().getFunction() }
717717

@@ -741,7 +741,7 @@ class InitialGlobalValue extends Node, TInitialGlobalValue {
741741
/** Gets the underlying SSA definition. */
742742
Ssa::GlobalDef getGlobalDef() { result = globalDef }
743743

744-
override Declaration getEnclosingCallable() { result = this.getFunction() }
744+
override DataFlowCallable getEnclosingCallable() { result = TSourceCallable(this.getFunction()) }
745745

746746
override Declaration getFunction() { result = globalDef.getIRFunction().getFunction() }
747747

@@ -778,7 +778,7 @@ class FlowSummaryNode extends Node, TFlowSummaryNode {
778778
* TODO: QLDoc.
779779
*/
780780
override DataFlowCallable getEnclosingCallable() {
781-
none() //result.asSummarizedCallable() = this.getSummarizedCallable() TODO
781+
result = TSummarizedCallable(this.getSummarizedCallable())
782782
}
783783

784784
override Location getLocationImpl() { result = this.getSummarizedCallable().getLocation() }
@@ -801,7 +801,7 @@ class IndirectParameterNode extends Node instanceof IndirectInstruction {
801801
/** Gets the parameter whose indirection is initialized. */
802802
Parameter getParameter() { result = init.getParameter() }
803803

804-
override Declaration getEnclosingCallable() { result = this.getFunction() }
804+
override DataFlowCallable getEnclosingCallable() { result = TSourceCallable(this.getFunction()) }
805805

806806
override Declaration getFunction() { result = init.getEnclosingFunction() }
807807

@@ -836,7 +836,7 @@ class IndirectReturnNode extends Node {
836836
.hasOperandAndIndirectionIndex(any(ReturnValueInstruction ret).getReturnAddressOperand(), _)
837837
}
838838

839-
override Declaration getEnclosingCallable() { result = this.getFunction() }
839+
override DataFlowCallable getEnclosingCallable() { result = TSourceCallable(this.getFunction()) }
840840

841841
/**
842842
* Holds if this node represents the value that is returned to the caller
@@ -1031,7 +1031,7 @@ private module RawIndirectNodes {
10311031
result = this.getOperand().getDef().getEnclosingFunction()
10321032
}
10331033

1034-
override Declaration getEnclosingCallable() { result = this.getFunction() }
1034+
override DataFlowCallable getEnclosingCallable() { result = TSourceCallable(this.getFunction()) }
10351035

10361036
override DataFlowType getType() {
10371037
exists(int sub, DataFlowType type, boolean isGLValue |
@@ -1073,7 +1073,7 @@ private module RawIndirectNodes {
10731073

10741074
override Declaration getFunction() { result = this.getInstruction().getEnclosingFunction() }
10751075

1076-
override Declaration getEnclosingCallable() { result = this.getFunction() }
1076+
override DataFlowCallable getEnclosingCallable() { result = TSourceCallable(this.getFunction()) }
10771077

10781078
override DataFlowType getType() {
10791079
exists(int sub, DataFlowType type, boolean isGLValue |
@@ -1171,7 +1171,7 @@ class FinalParameterNode extends Node, TFinalParameterNode {
11711171

11721172
override Declaration getFunction() { result = p.getFunction() }
11731173

1174-
override Declaration getEnclosingCallable() { result = this.getFunction() }
1174+
override DataFlowCallable getEnclosingCallable() { result = TSourceCallable(this.getFunction()) }
11751175

11761176
override DataFlowType getType() { result = getTypeImpl(p.getUnspecifiedType(), indirectionIndex) }
11771177

@@ -1704,7 +1704,7 @@ private predicate indirectParameterNodeHasArgumentIndexAndIndex(
17041704
/** A synthetic parameter to model the pointed-to object of a pointer parameter. */
17051705
class ParameterIndirectionNode extends ParameterNode instanceof IndirectParameterNode {
17061706
override predicate isParameterOf(Function f, ParameterPosition pos) {
1707-
IndirectParameterNode.super.getEnclosingCallable() = f and
1707+
IndirectParameterNode.super.getEnclosingCallable().asSourceCallable() = f and
17081708
exists(int argumentIndex, int indirectionIndex |
17091709
indirectPositionHasArgumentIndexAndIndex(pos, argumentIndex, indirectionIndex) and
17101710
indirectParameterNodeHasArgumentIndexAndIndex(this, argumentIndex, indirectionIndex)
@@ -1795,13 +1795,13 @@ class VariableNode extends Node, TVariableNode {
17951795

17961796
override Declaration getFunction() { none() }
17971797

1798-
override Declaration getEnclosingCallable() {
1798+
override DataFlowCallable getEnclosingCallable() {
17991799
// When flow crosses from one _enclosing callable_ to another, the
18001800
// interprocedural data-flow library discards call contexts and inserts a
18011801
// node in the big-step relation used for human-readable path explanations.
18021802
// Therefore we want a distinct enclosing callable for each `VariableNode`,
18031803
// and that can be the `Variable` itself.
1804-
result = v
1804+
result = TSourceCallable(v)
18051805
}
18061806

18071807
override DataFlowType getType() {
Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
1-
| tests.cpp:115:5:115:19 | [summary param] 0 in madArg0ToReturn | | madArg0ToReturn | |
2-
| tests.cpp:115:5:115:19 | [summary] to write: ReturnValue in madArg0ToReturn | | madArg0ToReturn | |
3-
| tests.cpp:117:5:117:28 | [summary param] 0 in madArg0ToReturnValueFlow | | madArg0ToReturnValueFlow | |
4-
| tests.cpp:117:5:117:28 | [summary] to write: ReturnValue in madArg0ToReturnValueFlow | | madArg0ToReturnValueFlow | |
5-
| tests.cpp:119:6:119:18 | [summary param] 0 in madArg0ToArg1 | | madArg0ToArg1 | |
6-
| tests.cpp:119:6:119:18 | [summary param] 1 in madArg0ToArg1 | | madArg0ToArg1 | |
7-
| tests.cpp:119:6:119:18 | [summary] to write: Argument[1] in madArg0ToArg1 | | madArg0ToArg1 | |
8-
| tests.cpp:180:7:180:19 | [summary param] 0 in madArg0ToSelf | | madArg0ToSelf | |
9-
| tests.cpp:180:7:180:19 | [summary param] this in madArg0ToSelf | | madArg0ToSelf | |
10-
| tests.cpp:180:7:180:19 | [summary] to write: Argument[this] in madArg0ToSelf | | madArg0ToSelf | |
11-
| tests.cpp:181:6:181:20 | [summary param] this in madSelfToReturn | | madSelfToReturn | |
12-
| tests.cpp:181:6:181:20 | [summary] to write: ReturnValue in madSelfToReturn | | madSelfToReturn | |
13-
| tests.cpp:209:7:209:30 | [summary param] this in namespaceMadSelfToReturn | | namespaceMadSelfToReturn | |
14-
| tests.cpp:209:7:209:30 | [summary] to write: ReturnValue in namespaceMadSelfToReturn | | namespaceMadSelfToReturn | |
1+
| tests.cpp:115:5:115:19 | [summary param] 0 in madArg0ToReturn | | madArg0ToReturn | madArg0ToReturn |
2+
| tests.cpp:115:5:115:19 | [summary] to write: ReturnValue in madArg0ToReturn | | madArg0ToReturn | madArg0ToReturn |
3+
| tests.cpp:117:5:117:28 | [summary param] 0 in madArg0ToReturnValueFlow | | madArg0ToReturnValueFlow | madArg0ToReturnValueFlow |
4+
| tests.cpp:117:5:117:28 | [summary] to write: ReturnValue in madArg0ToReturnValueFlow | | madArg0ToReturnValueFlow | madArg0ToReturnValueFlow |
5+
| tests.cpp:119:6:119:18 | [summary param] 0 in madArg0ToArg1 | | madArg0ToArg1 | madArg0ToArg1 |
6+
| tests.cpp:119:6:119:18 | [summary param] 1 in madArg0ToArg1 | | madArg0ToArg1 | madArg0ToArg1 |
7+
| tests.cpp:119:6:119:18 | [summary] to write: Argument[1] in madArg0ToArg1 | | madArg0ToArg1 | madArg0ToArg1 |
8+
| tests.cpp:180:7:180:19 | [summary param] 0 in madArg0ToSelf | | madArg0ToSelf | madArg0ToSelf |
9+
| tests.cpp:180:7:180:19 | [summary param] this in madArg0ToSelf | | madArg0ToSelf | madArg0ToSelf |
10+
| tests.cpp:180:7:180:19 | [summary] to write: Argument[this] in madArg0ToSelf | | madArg0ToSelf | madArg0ToSelf |
11+
| tests.cpp:181:6:181:20 | [summary param] this in madSelfToReturn | | madSelfToReturn | madSelfToReturn |
12+
| tests.cpp:181:6:181:20 | [summary] to write: ReturnValue in madSelfToReturn | | madSelfToReturn | madSelfToReturn |
13+
| tests.cpp:209:7:209:30 | [summary param] this in namespaceMadSelfToReturn | | namespaceMadSelfToReturn | namespaceMadSelfToReturn |
14+
| tests.cpp:209:7:209:30 | [summary] to write: ReturnValue in namespaceMadSelfToReturn | | namespaceMadSelfToReturn | namespaceMadSelfToReturn |

0 commit comments

Comments
 (0)