Skip to content

Commit bf007c9

Browse files
committed
C++: Adapt to FlowSummaryImpl changes
1 parent e258840 commit bf007c9

6 files changed

Lines changed: 239 additions & 213 deletions

File tree

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

Lines changed: 88 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -15,30 +15,9 @@ private import semmle.code.cpp.ir.IR
1515
module Input implements InputSig<Location, DataFlowImplSpecific::CppDataFlow> {
1616
class SummarizedCallableBase = Function;
1717

18-
abstract private class SourceSinkBase extends Element {
19-
/** Gets the call associated with this element, if any. */
20-
CallInstruction getCall() { none() }
18+
class SourceBase = Function;
2119

22-
/** Gets the function associated with this element, if any. */
23-
Function getFunction() { none() }
24-
25-
/** Gets the enclosing function of this element. */
26-
abstract Declaration getEnclosingFunction();
27-
}
28-
29-
abstract class SourceBase extends SourceSinkBase { }
30-
31-
abstract class SinkBase extends SourceSinkBase { }
32-
33-
private class SourceSinkCall extends SourceBase, SinkBase instanceof Call {
34-
CallInstruction call;
35-
36-
SourceSinkCall() { call.getUnconvertedResultExpression() = this }
37-
38-
final override CallInstruction getCall() { result = call }
39-
40-
final override Declaration getEnclosingFunction() { result = Call.super.getEnclosingFunction() }
41-
}
20+
class SinkBase = Function;
4221

4322
class FlowSummaryCallBase = CallInstruction;
4423

@@ -151,65 +130,110 @@ module Input implements InputSig<Location, DataFlowImplSpecific::CppDataFlow> {
151130

152131
private import Make<Location, DataFlowImplSpecific::CppDataFlow, Input> as Impl
153132

154-
private module StepsInput implements Impl::Private::StepsInputSig {
155-
Impl::Private::SummaryNode getSummaryNode(Node n) {
156-
result = n.(FlowSummaryNode).getSummaryNode()
157-
}
133+
module Input2 implements Impl::Private::InputSig2 {
134+
class SourceSinkReportingElement extends Element {
135+
private Function getEnclosingFunction() {
136+
result = this.(StmtParent).getEnclosingFunction()
137+
or
138+
this = result.getAParameter()
139+
}
158140

159-
DataFlowCall getACall(Public::SummarizedCallable sc) {
160-
result.getStaticCallTarget().getUnderlyingCallable() = sc
141+
DataFlowCallable getEnclosingCallable() {
142+
result.asSourceCallable() = this.getEnclosingFunction()
143+
}
161144
}
162145

163-
Node getSourceOutNode(Input::FlowSummaryCallBase call, ReturnKind rk) {
164-
exists(IndirectReturnOutNode out | result = out |
165-
out.getCallInstruction() = call and
166-
pragma[only_bind_out](rk.(NormalReturnKind).getIndirectionIndex()) =
167-
pragma[only_bind_out](out.getIndirectionIndex())
146+
private SourceSinkReportingElement getSourceSinkArgumentElement(
147+
Call call, Impl::Private::SummaryComponent sc
148+
) {
149+
exists(Position pos, int i |
150+
sc = Impl::Private::SummaryComponent::argument(pos) and
151+
i = pos.getArgumentIndex()
152+
|
153+
result = call.getArgument(i)
154+
or
155+
i = -1 and
156+
result = call.getQualifier()
168157
)
169158
}
170159

171-
DataFlowCallable getSourceNodeEnclosingCallable(Input::SourceBase source) {
172-
result.asSourceCallable() = source.getEnclosingFunction()
160+
SourceSinkReportingElement getSourceEntryElement(
161+
Impl::Public::SourceElement source, Impl::Private::SummaryComponentStack s
162+
) {
163+
s.headOfSingleton() = Impl::Private::SummaryComponent::return(_) and
164+
result.(Call).getTarget() = source
165+
or
166+
exists(Position pos, Function f |
167+
s.head() = Impl::Private::SummaryComponent::parameter(pos) and
168+
result = f.getParameter(pos.getArgumentIndex())
169+
|
170+
// TODO: callbacks
171+
// exists(Call call |
172+
// call.getTarget() = source and
173+
// f = getSourceSinkArgumentElement(call, s.tail().headOfSingleton())
174+
// )
175+
// or
176+
s.length() = 1 and
177+
f = source
178+
)
179+
or
180+
exists(Call call |
181+
call.getTarget() = source and
182+
result = getSourceSinkArgumentElement(call, s.headOfSingleton())
183+
)
173184
}
174185

175-
private ArgumentNode getSourceNodeArgument(
176-
Input::SourceBase source, Impl::Private::SummaryComponent sc
177-
) {
186+
private ArgumentNode getSourceNodeArgument(Call c, Impl::Private::SummaryComponent sc) {
178187
exists(Position pos, DataFlowCall call |
179188
sc = Impl::Private::SummaryComponent::argument(pos) and
180-
source.getCall() = call.asCallInstruction() and
189+
c = call.asCallInstruction().getUnconvertedResultExpression() and
181190
result.argumentOf(call, pos)
182191
)
183192
}
184193

185-
Node getSourceNode(Input::SourceBase source, Impl::Private::SummaryComponentStack s) {
194+
bindingset[e, s]
195+
Node getSourceExitNode(SourceSinkReportingElement e, Impl::Private::SummaryComponentStack s) {
186196
exists(ReturnKind rk, DataFlowCall call |
187197
s.head() = Impl::Private::SummaryComponent::return(rk) and
188-
source.getCall() = call.asCallInstruction() and
198+
call.asCallInstruction().getUnconvertedResultExpression() = e and
189199
result = getAnOutNode(call, rk)
190200
)
191201
or
192-
exists(Position pos, DataFlowCallable callable |
193-
s.head() = Impl::Private::SummaryComponent::parameter(pos) and
194-
result.(ParameterNode).isParameterOf(callable, pos)
195-
|
196-
exists(ArgumentNode arg, DataFlowCall call |
197-
arg = getSourceNodeArgument(source, s.tail().headOfSingleton()) and
198-
arg.argumentOf(call, pos) and
199-
callable = call.getStaticCallTarget()
200-
)
201-
or
202-
source.getFunction() = callable.asSourceCallable()
203-
)
202+
result.(ParameterNode).getParameter() = e
204203
or
205-
exists(Position pos |
206-
s.head() = Impl::Private::SummaryComponent::argument(pos) and
207-
result.(PostUpdateNode).getPreUpdateNode() =
208-
getSourceNodeArgument(source, s.headOfSingleton())
204+
exists(Call call, Impl::Private::SummaryComponent arg |
205+
arg = s.headOfSingleton() and
206+
e = getSourceSinkArgumentElement(call, arg) and
207+
result.(PostUpdateNode).getPreUpdateNode() = getSourceNodeArgument(call, arg)
209208
)
210209
}
211210

212-
Node getSinkNode(Input::SinkBase sink, Impl::Private::SummaryComponent sc) { none() }
211+
bindingset[e, sc]
212+
Node getSinkEntryNode(SourceSinkReportingElement e, Impl::Private::SummaryComponent sc) { none() }
213+
214+
SourceSinkReportingElement getSinkExitElement(
215+
Impl::Public::SinkElement sink, Impl::Private::SummaryComponent sc
216+
) {
217+
none()
218+
}
219+
}
220+
221+
private import Impl::Private::Make2<Input2> as Impl2
222+
223+
private module StepsInput implements Impl2::StepsInputSig {
224+
Impl2::SummaryNode getSummaryNode(Node n) { result = n.(FlowSummaryNode).getSummaryNode() }
225+
226+
DataFlowCall getACall(Public::SummarizedCallable sc) {
227+
result.getStaticCallTarget().getUnderlyingCallable() = sc
228+
}
229+
230+
Node getSourceOutNode(Input::FlowSummaryCallBase call, ReturnKind rk) {
231+
exists(IndirectReturnOutNode out | result = out |
232+
out.getCallInstruction() = call and
233+
pragma[only_bind_out](rk.(NormalReturnKind).getIndirectionIndex()) =
234+
pragma[only_bind_out](out.getIndirectionIndex())
235+
)
236+
}
213237
}
214238

215239
module SourceSinkInterpretationInput implements
@@ -326,8 +350,9 @@ module SourceSinkInterpretationInput implements
326350

327351
module Private {
328352
import Impl::Private
353+
import Impl2
329354

330-
module Steps = Impl::Private::Steps<StepsInput>;
355+
module Steps = Impl2::Steps<StepsInput>;
331356

332357
module External {
333358
import Impl::Private::External
@@ -367,17 +392,17 @@ module Private {
367392

368393
module Public = Impl::Public;
369394

370-
private class SourceModelCall extends Public::SourceElement instanceof Call {
395+
private class SourceModel extends Public::SourceElement {
371396
private string namespace;
372397
private string type;
373398
private boolean subtypes;
374399
private string name;
375400
private string signature;
376401
private string ext;
377402

378-
SourceModelCall() {
403+
SourceModel() {
379404
sourceModel(namespace, type, subtypes, name, signature, ext, _, _, _, _) and
380-
this.getTarget() = interpretElement(namespace, type, subtypes, name, signature, ext)
405+
this = interpretElement(namespace, type, subtypes, name, signature, ext)
381406
}
382407

383408
override predicate isSource(

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

Lines changed: 3 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1527,23 +1527,6 @@ class FlowSummaryNode extends Node, TFlowSummaryNode {
15271527
*/
15281528
FlowSummaryImpl::Private::SummaryNode getSummaryNode() { this = TFlowSummaryNode(result) }
15291529

1530-
/**
1531-
* Gets the summarized callable that this node belongs to.
1532-
*/
1533-
FlowSummaryImpl::Public::SummarizedCallable getSummarizedCallable() {
1534-
result = this.getSummaryNode().getSummarizedCallable()
1535-
}
1536-
1537-
/** Gets the source element that this node belongs to, if any. */
1538-
FlowSummaryImpl::Public::SourceElement getSourceElement() {
1539-
result = this.getSummaryNode().getSourceElement()
1540-
}
1541-
1542-
/** Gets the sink element that this node belongs to, if any. */
1543-
FlowSummaryImpl::Public::SinkElement getSinkElement() {
1544-
result = this.getSummaryNode().getSinkElement()
1545-
}
1546-
15471530
/** Holds if this node is a source node of kind `kind`. */
15481531
predicate isSource(string kind, string model) {
15491532
this.getSummaryNode().(FlowSummaryImpl::Private::SourceOutputNode).isEntry(kind, model)
@@ -1559,21 +1542,10 @@ class FlowSummaryNode extends Node, TFlowSummaryNode {
15591542
* summarized function this node is part of.
15601543
*/
15611544
override DataFlowCallable getEnclosingCallable() {
1562-
result = FlowSummaryImpl::Private::getEnclosingCallable(this.getSummaryNode())
1563-
or
1564-
// TODO: This could actually be done by the shared library.
1565-
result.asSourceCallable() = this.getSourceElement().getEnclosingFunction()
1566-
or
1567-
result.asSourceCallable() = this.getSinkElement().getEnclosingFunction()
1545+
result = this.getSummaryNode().getEnclosingCallable()
15681546
}
15691547

1570-
override Location getLocationImpl() {
1571-
result = this.getSummarizedCallable().getLocation()
1572-
or
1573-
result = this.getSourceElement().getLocation()
1574-
or
1575-
result = this.getSinkElement().getLocation()
1576-
}
1548+
override Location getLocationImpl() { result = this.getSummaryNode().getLocation() }
15771549

15781550
override string toStringImpl() { result = this.getSummaryNode().toString() }
15791551
}
@@ -1815,7 +1787,7 @@ class SummaryParameterNode extends AbstractParameterNode, FlowSummaryNode {
18151787
override predicate isSummaryParameterOf(
18161788
FlowSummaryImpl::Public::SummarizedCallable c, ParameterPosition p
18171789
) {
1818-
c = this.getSummarizedCallable() and
1790+
c = this.getSummaryNode().getSummarizedCallable() and
18191791
p = this.getPosition()
18201792
}
18211793
}

0 commit comments

Comments
 (0)