Skip to content

Commit

Permalink
Merge pull request #17788 from MathiasVP/better-function-pointer-reso…
Browse files Browse the repository at this point in the history
…lution

C++: Improve function pointer resolution
  • Loading branch information
MathiasVP authored Oct 17, 2024
2 parents 7d62cda + 5e04358 commit b9205b1
Show file tree
Hide file tree
Showing 7 changed files with 46 additions and 1 deletion.
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
---
category: minorAnalysis
---
* The function call target resolution algorithm has been improved to resolve more calls through function pointers. As a result, dataflow queries may have more results.
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
---
category: feature
---
* Added a new predicate `DataFlow::getARuntimeTarget` for getting a function that may be invoked by a `Call` expression. Unlike `Call.getTarget` this new predicate may also resolve function pointers.
Original file line number Diff line number Diff line change
Expand Up @@ -1328,7 +1328,10 @@ predicate lambdaCreation(Node creation, LambdaCallKind kind, DataFlowCallable c)

/** Holds if `call` is a lambda call of kind `kind` where `receiver` is the lambda expression. */
predicate lambdaCall(DataFlowCall call, LambdaCallKind kind, Node receiver) {
call.(SummaryCall).getReceiver() = receiver.(FlowSummaryNode).getSummaryNode() and
(
call.(SummaryCall).getReceiver() = receiver.(FlowSummaryNode).getSummaryNode() or
call.asCallInstruction().getCallTargetOperand() = receiver.asOperand()
) and
exists(kind)
}

Expand Down
14 changes: 14 additions & 0 deletions cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowUtil.qll
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ private import SsaInternals as Ssa
private import DataFlowImplCommon as DataFlowImplCommon
private import codeql.util.Unit
private import Node0ToString
private import DataFlowDispatch as DataFlowDispatch
import ExprNodes

/**
Expand Down Expand Up @@ -2497,3 +2498,16 @@ class AdditionalCallTarget extends Unit {
*/
abstract Declaration viableTarget(Call call);
}

/**
* Gets a function that may be called by `call`.
*
* Note that `call` may be a call to a function pointer expression.
*/
Function getARuntimeTarget(Call call) {
exists(DataFlowCall dfCall | dfCall.asCallInstruction().getUnconvertedResultExpression() = call |
result = DataFlowDispatch::viableCallable(dfCall).asSourceCallable()
or
result = DataFlowImplCommon::viableCallableLambda(dfCall, _).asSourceCallable()
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ uniqueEnclosingCallable
| test.cpp:864:47:864:54 | call to source | Node should have one enclosing callable but has 0. |
| test.cpp:872:46:872:51 | call to source | Node should have one enclosing callable but has 0. |
| test.cpp:872:53:872:56 | 1 | Node should have one enclosing callable but has 0. |
| test.cpp:1126:33:1129:1 | {...} | Node should have one enclosing callable but has 0. |
| test.cpp:1127:3:1127:13 | reads_input | Node should have one enclosing callable but has 0. |
| test.cpp:1128:3:1128:21 | not_does_read_input | Node should have one enclosing callable but has 0. |
uniqueCallEnclosingCallable
| test.cpp:864:47:864:54 | call to source | Call should have one enclosing callable but has 0. |
| test.cpp:872:46:872:51 | call to source | Call should have one enclosing callable but has 0. |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -323,6 +323,7 @@ irFlow
| test.cpp:1069:9:1069:14 | call to source | test.cpp:1074:10:1074:10 | i |
| test.cpp:1069:9:1069:14 | call to source | test.cpp:1081:10:1081:10 | i |
| test.cpp:1117:27:1117:34 | call to source | test.cpp:1117:27:1117:34 | call to source |
| test.cpp:1132:11:1132:16 | call to source | test.cpp:1121:8:1121:8 | x |
| true_upon_entry.cpp:9:11:9:16 | call to source | true_upon_entry.cpp:13:8:13:8 | x |
| true_upon_entry.cpp:17:11:17:16 | call to source | true_upon_entry.cpp:21:8:21:8 | x |
| true_upon_entry.cpp:27:9:27:14 | call to source | true_upon_entry.cpp:29:8:29:8 | x |
Expand Down
16 changes: 16 additions & 0 deletions cpp/ql/test/library-tests/dataflow/dataflow-tests/test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1115,4 +1115,20 @@ void indirect_sink_const_ref(const T&);

void test_temp_with_conversion_from_materialization() {
indirect_sink_const_ref(source()); // $ ir MISSING: ast
}

void reads_input(int x) {
sink(x); // $ ir MISSING: ast
}

void not_does_read_input(int x);

void (*dispatch_table[])(int) = {
reads_input,
not_does_read_input
};

void test_dispatch_table(int i) {
int x = source();
dispatch_table[i](x);
}

0 comments on commit b9205b1

Please sign in to comment.