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

Skip to content

Commit e1a5a84

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

5 files changed

Lines changed: 134 additions & 12 deletions

File tree

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,9 @@ module SourceSinkInterpretationInput implements
114114
Node asNode() { this = TNode_(result) }
115115

116116
/** Gets the call that this node corresponds to, if any. */
117-
DataFlowCall asCall() { this.asElement() = result.getUnconvertedResultExpression() }
117+
DataFlowCall asCall() { this.asElement() = result.asCallInstruction().getUnconvertedResultExpression()
118+
// TODO: or summary call?
119+
}
118120

119121
/** Gets the callable that this node corresponds to, if any. */
120122
DataFlowCallable asCallable() { result.(Function) = this.asElement() }

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ DataFlowCallable defaultViableCallable(DataFlowCall call) {
2323
// function with the right signature is present in the database, we return
2424
// that as a potential callee.
2525
exists(string qualifiedName, int nparams |
26-
callSignatureWithoutBody(qualifiedName, nparams, call) and
26+
callSignatureWithoutBody(qualifiedName, nparams, call.asCallInstruction()) and
2727
functionSignatureWithBody(qualifiedName, nparams, result) and
2828
strictcount(Function other | functionSignatureWithBody(qualifiedName, nparams, other)) = 1
2929
)
@@ -40,7 +40,7 @@ DataFlowCallable viableCallable(DataFlowCall call) {
4040
result = defaultViableCallable(call)
4141
or
4242
// Additional call targets
43-
result = any(AdditionalCallTarget additional).viableTarget(call.getUnconvertedResultExpression())
43+
result = any(AdditionalCallTarget additional).viableTarget(call.asCallInstruction().getUnconvertedResultExpression())
4444
}
4545

4646
/**
@@ -179,7 +179,7 @@ private module VirtualDispatch {
179179
exists(this.getStaticCallTarget().(VirtualFunction).getAnOverridingFunction())
180180
}
181181

182-
override DataFlow::Node getDispatchValue() { result.asInstruction() = this.getThisArgument() }
182+
override DataFlow::Node getDispatchValue() { result.asInstruction() = this.getArgument(-1) }
183183

184184
override MemberFunction resolve() {
185185
exists(Class overridingClass |

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

Lines changed: 124 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ private import DataFlowUtil
33
private import semmle.code.cpp.ir.IR
44
private import DataFlowDispatch
55
private import semmle.code.cpp.ir.internal.IRCppLanguage
6+
private import semmle.code.cpp.dataflow.internal.FlowSummaryImpl as FlowSummaryImpl
67
private import SsaInternals as Ssa
78
private import DataFlowImplCommon as DataFlowImplCommon
89
private import codeql.util.Unit
@@ -381,12 +382,26 @@ private class SideEffectArgumentNode extends ArgumentNode, SideEffectOperandNode
381382
override predicate argumentOf(DataFlowCall dfCall, ArgumentPosition pos) {
382383
exists(int indirectionIndex |
383384
pos = TIndirectionPosition(argumentIndex, pragma[only_bind_into](indirectionIndex)) and
384-
this.getCallInstruction() = dfCall and
385+
this.getCallInstruction() = dfCall.asCallInstruction() and // TODO: or summarized call?
385386
super.hasAddressOperandAndIndirectionIndex(_, pragma[only_bind_into](indirectionIndex))
386387
)
387388
}
388389
}
389390

391+
class SummaryArgumentNode extends ArgumentNode, FlowSummaryNode {
392+
private SummaryCall call_;
393+
private ArgumentPosition pos_;
394+
395+
SummaryArgumentNode() {
396+
FlowSummaryImpl::Private::summaryArgumentNode(call_.getReceiver(), this.getSummaryNode(), pos_)
397+
}
398+
399+
override predicate argumentOf(DataFlowCall call, ArgumentPosition pos) {
400+
call = call_ and
401+
pos = pos_
402+
}
403+
}
404+
390405
/** A parameter position represented by an integer. */
391406
class ParameterPosition = Position;
392407

@@ -659,19 +674,19 @@ private class DirectCallOutNode extends OutNode {
659674

660675
DirectCallOutNode() { simpleOutNode(this, call) }
661676

662-
override DataFlowCall getCall() { result = call }
677+
override DataFlowCall getCall() { result.asCallInstruction() = call } // TODO: or summarized call?
663678

664679
override ReturnKind getReturnKind() { result = TNormalReturnKind(0) }
665680
}
666681

667682
private class IndirectCallOutNode extends OutNode, IndirectReturnOutNode {
668-
override DataFlowCall getCall() { result = this.getCallInstruction() }
683+
override DataFlowCall getCall() { result.asCallInstruction() = this.getCallInstruction() } // TODO: or summarized call?
669684

670685
override ReturnKind getReturnKind() { result = TNormalReturnKind(this.getIndirectionIndex()) }
671686
}
672687

673688
private class SideEffectOutNode extends OutNode, IndirectArgumentOutNode {
674-
override DataFlowCall getCall() { result = this.getCallInstruction() }
689+
override DataFlowCall getCall() { result.asCallInstruction() = this.getCallInstruction() } // TODO: or summarized call?
675690

676691
override ReturnKind getReturnKind() {
677692
result = TIndirectReturnKind(this.getArgumentIndex(), this.getIndirectionIndex())
@@ -938,9 +953,111 @@ class DataFlowExpr = Expr;
938953

939954
class DataFlowType = Type;
940955

941-
/** A function call relevant for data flow. */
942-
class DataFlowCall extends CallInstruction {
943-
DataFlowCallable getEnclosingCallable() { result = this.getEnclosingFunction() }
956+
cached
957+
newtype TDataFlowCall =
958+
TNormalCall(CallInstruction call) or
959+
TSummaryCall(
960+
FlowSummaryImpl::Public::SummarizedCallable c, FlowSummaryImpl::Private::SummaryNode receiver
961+
) {
962+
FlowSummaryImpl::Private::summaryCallbackRange(c, receiver)
963+
}
964+
965+
/**
966+
* A function call relevant for data flow. This includes calls from source
967+
* code and calls inside library callables with a flow summary.
968+
*/
969+
class DataFlowCall extends TDataFlowCall {
970+
/**
971+
* Gets the underlying data flow call instruction, if any.
972+
*/
973+
CallInstruction asCallInstruction() { none() }
974+
975+
/**
976+
* Gets the operand the specifies the target function of the call.
977+
*/
978+
CallTargetOperand getCallTargetOperand() { none() }
979+
980+
/**
981+
* Gets the `Function` that the call targets, if this is statically known.
982+
*/
983+
Function getStaticCallTarget() { none() }
984+
985+
/**
986+
* Gets the `index`'th argument operand. The qualifier is considered to have index `-1`.
987+
*/
988+
ArgumentOperand getArgumentOperand(int index) { none() }
989+
990+
/**
991+
* Gets the argument at the specified index, or `this` if `index` is `-1`.
992+
*/
993+
pragma[noinline]
994+
final Instruction getArgument(int index) { result = this.getArgumentOperand(index).getDef() }
995+
996+
/**
997+
* Gets the number of arguments of the call, including the `this` pointer, if any.
998+
*/
999+
final int getNumberOfArguments() { result = count(this.getArgumentOperand(_)) }
1000+
1001+
/**
1002+
* Gets the enclosing callable, if any.
1003+
*/
1004+
DataFlowCallable getEnclosingCallable() { none() }
1005+
1006+
/**
1007+
* Gets a textual representation of this call.
1008+
*/
1009+
string toString() { none() }
1010+
1011+
/**
1012+
* Gets the location of this call.
1013+
*/
1014+
Location getLocation() { none() }
1015+
}
1016+
1017+
private class NormalCall extends DataFlowCall, TNormalCall {
1018+
private CallInstruction call;
1019+
1020+
NormalCall() { this = TNormalCall(call) }
1021+
1022+
override CallInstruction asCallInstruction() { result = call }
1023+
1024+
override CallTargetOperand getCallTargetOperand() { result = call.getCallTargetOperand() }
1025+
1026+
override Function getStaticCallTarget() { result = call.getStaticCallTarget() }
1027+
1028+
override ArgumentOperand getArgumentOperand(int index) {
1029+
result = call.getArgumentOperand(index)
1030+
}
1031+
1032+
override DataFlowCallable getEnclosingCallable() { result = call.getEnclosingFunction() }
1033+
1034+
override string toString() { result = call.toString() }
1035+
1036+
override Location getLocation() { result = call.getLocation() }
1037+
}
1038+
1039+
class SummaryCall extends DataFlowCall, TSummaryCall {
1040+
private FlowSummaryImpl::Public::SummarizedCallable c;
1041+
private FlowSummaryImpl::Private::SummaryNode receiver;
1042+
1043+
SummaryCall() { this = TSummaryCall(c, receiver) }
1044+
1045+
/** Gets the data flow node that this call targets. */
1046+
FlowSummaryImpl::Private::SummaryNode getReceiver() { result = receiver }
1047+
1048+
// override CallTargetOperand getCallTargetOperand() TODO
1049+
1050+
override Function getStaticCallTarget() { // TODO: should this return DataFlowCallable?
1051+
result = c
1052+
}
1053+
1054+
// override ArgumentOperand getArgumentOperand(int index) TODO
1055+
1056+
// override DataFlowCallable getEnclosingCallable() { result = TSummarizedCallable(c) } TODO
1057+
1058+
override string toString() { result = "[summary] call to " + receiver + " in " + c }
1059+
1060+
override UnknownLocation getLocation() { any() }
9441061
}
9451062

9461063
module IsUnreachableInCall {

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -877,6 +877,9 @@ class IndirectArgumentOutNode extends PostUpdateNodeImpl {
877877

878878
CallInstruction getCallInstruction() { result.getAnArgumentOperand() = operand }
879879

880+
/**
881+
* Gets the `Function` that the call targets, if this is statically known.
882+
*/
880883
Function getStaticCallTarget() { result = this.getCallInstruction().getStaticCallTarget() }
881884

882885
override string toStringImpl() {

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -740,7 +740,7 @@ private predicate isArgumentOfCallableInstruction(DataFlowCall call, Instruction
740740
}
741741

742742
private predicate isArgumentOfCallableOperand(DataFlowCall call, Operand operand) {
743-
operand.(ArgumentOperand).getCall() = call
743+
operand = call.getArgumentOperand(_)
744744
or
745745
exists(FieldAddressInstruction fai |
746746
fai.getObjectAddressOperand() = operand and

0 commit comments

Comments
 (0)