Skip to content

Commit 65615a7

Browse files
committed
C++: Fix join in virtual dispatch's 'returnStep' predicate.
1 parent 1c6516e commit 65615a7

1 file changed

Lines changed: 23 additions & 4 deletions

File tree

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

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,15 @@ private predicate qualifierSourceImpl(RelevantNode n, Class c) {
131131
)
132132
}
133133

134+
pragma[nomagic]
135+
private predicate hasKindAndEnclosingCallable(
136+
DataFlowPrivate::DataFlowCallable callable, DataFlowPrivate::ReturnKind kind,
137+
DataFlowPrivate::ReturnNode return
138+
) {
139+
return.getEnclosingCallable() = callable and
140+
return.getKind() = kind
141+
}
142+
134143
private module TrackVirtualDispatch<methodDispatchSig/1 virtualDispatch0> {
135144
/**
136145
* Gets a possible runtime target of `c` using both static call-target
@@ -197,11 +206,21 @@ private module TrackVirtualDispatch<methodDispatchSig/1 virtualDispatch0> {
197206
)
198207
}
199208

209+
pragma[nomagic]
210+
private predicate hasDispatchWithKind(
211+
DataFlowPrivate::DataFlowCallable callable, DataFlowPrivate::ReturnKind kind,
212+
LocalSourceNode n2
213+
) {
214+
exists(DataFlowPrivate::DataFlowCall call |
215+
n2 = DataFlowPrivate::getAnOutNode(call, kind) and
216+
callable = dispatch(call)
217+
)
218+
}
219+
200220
predicate returnStep(Node n1, LocalSourceNode n2) {
201-
exists(DataFlowPrivate::DataFlowCallable callable, DataFlowPrivate::DataFlowCall call |
202-
n1.(DataFlowPrivate::ReturnNode).getEnclosingCallable() = callable and
203-
callable = dispatch(call) and
204-
n2 = DataFlowPrivate::getAnOutNode(call, n1.(DataFlowPrivate::ReturnNode).getKind())
221+
exists(DataFlowPrivate::DataFlowCallable callable, DataFlowPrivate::ReturnKind kind |
222+
hasKindAndEnclosingCallable(callable, kind, n1) and
223+
hasDispatchWithKind(callable, kind, n2)
205224
)
206225
}
207226

0 commit comments

Comments
 (0)