mirror of
https://github.com/github/codeql.git
synced 2026-04-28 02:05:14 +02:00
Merge pull request #2638 from jbj/ir-dispatch
C++ IR: Support for global virtual dispatch
This commit is contained in:
@@ -44,3 +44,89 @@ void VirtualDispatch(Bottom *bottomPtr, Bottom &bottomRef) {
|
||||
sink(topRef.notSource2()); // no flow [FALSE POSITIVE]
|
||||
topRef.notSink(source()); // no flow [FALSE POSITIVE]
|
||||
}
|
||||
|
||||
Top *globalBottom, *globalMiddle;
|
||||
|
||||
Top *readGlobalBottom() {
|
||||
return globalBottom;
|
||||
}
|
||||
|
||||
void DispatchThroughGlobal() {
|
||||
sink(globalBottom->isSource1()); // flow [NOT DETECTED by AST]
|
||||
sink(globalMiddle->isSource1()); // no flow
|
||||
|
||||
sink(readGlobalBottom()->isSource1()); // flow [NOT DETECTED by AST]
|
||||
|
||||
globalBottom = new Bottom();
|
||||
globalMiddle = new Middle();
|
||||
}
|
||||
|
||||
Top *allocateBottom() {
|
||||
return new Bottom();
|
||||
}
|
||||
|
||||
void callSinkByPointer(Top *top) {
|
||||
top->isSink(source()); // flow [NOT DETECTED by AST]
|
||||
}
|
||||
|
||||
void callSinkByReference(Top &top) {
|
||||
top.isSink(source()); // flow [NOT DETECTED by AST]
|
||||
}
|
||||
|
||||
void globalVirtualDispatch() {
|
||||
callSinkByPointer(allocateBottom());
|
||||
callSinkByReference(*allocateBottom());
|
||||
|
||||
Top *x = allocateBottom();
|
||||
x->isSink(source()); // flow [NOT DETECTED by AST]
|
||||
}
|
||||
|
||||
Top *identity(Top *top) {
|
||||
return top;
|
||||
}
|
||||
|
||||
void callIdentityFunctions(Top *top, Bottom *bottom) {
|
||||
identity(bottom)->isSink(source()); // flow [NOT DETECTED]
|
||||
identity(top)->isSink(source()); // now flow
|
||||
}
|
||||
|
||||
using SinkFunctionType = void (*)(int);
|
||||
|
||||
void callSink(int x) {
|
||||
sink(x);
|
||||
}
|
||||
|
||||
SinkFunctionType returnCallSink() {
|
||||
return callSink;
|
||||
}
|
||||
|
||||
void testFunctionPointer(SinkFunctionType maybeCallSink, SinkFunctionType dontCallSink, bool b) {
|
||||
if (b) {
|
||||
maybeCallSink = returnCallSink();
|
||||
}
|
||||
maybeCallSink(source()); // flow [NOT DETECTED by AST]
|
||||
dontCallSink(source()); // no flow
|
||||
}
|
||||
|
||||
namespace virtual_inheritance {
|
||||
struct Top {
|
||||
virtual int isSource() { return 0; }
|
||||
};
|
||||
|
||||
struct Middle : virtual Top {
|
||||
int isSource() override { return source(); }
|
||||
};
|
||||
|
||||
struct Bottom : Middle {
|
||||
};
|
||||
|
||||
void VirtualDispatch(Bottom *bottomPtr, Bottom &bottomRef) {
|
||||
// Because the inheritance from `Top` is virtual, the following casts go
|
||||
// directly from `Bottom` to `Top`, skipping `Middle`. That means we don't
|
||||
// get flow from a `Middle` value to the call qualifier.
|
||||
Top *topPtr = bottomPtr, &topRef = bottomRef;
|
||||
|
||||
sink(topPtr->isSource()); // flow [NOT DETECTED]
|
||||
sink(topRef.isSource()); // flow [NOT DETECTED]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,8 +10,14 @@
|
||||
| dispatch.cpp:16:37:16:42 | dispatch.cpp:40:15:40:23 | IR only |
|
||||
| dispatch.cpp:22:37:22:42 | dispatch.cpp:31:16:31:24 | IR only |
|
||||
| dispatch.cpp:22:37:22:42 | dispatch.cpp:39:15:39:23 | IR only |
|
||||
| dispatch.cpp:22:37:22:42 | dispatch.cpp:55:22:55:30 | IR only |
|
||||
| dispatch.cpp:22:37:22:42 | dispatch.cpp:58:28:58:36 | IR only |
|
||||
| dispatch.cpp:33:18:33:23 | dispatch.cpp:23:38:23:38 | IR only |
|
||||
| dispatch.cpp:41:17:41:22 | dispatch.cpp:23:38:23:38 | IR only |
|
||||
| dispatch.cpp:69:15:69:20 | dispatch.cpp:23:38:23:38 | IR only |
|
||||
| dispatch.cpp:73:14:73:19 | dispatch.cpp:23:38:23:38 | IR only |
|
||||
| dispatch.cpp:81:13:81:18 | dispatch.cpp:23:38:23:38 | IR only |
|
||||
| dispatch.cpp:107:17:107:22 | dispatch.cpp:96:8:96:8 | IR only |
|
||||
| lambdas.cpp:8:10:8:15 | lambdas.cpp:14:3:14:6 | AST only |
|
||||
| lambdas.cpp:8:10:8:15 | lambdas.cpp:18:8:18:8 | AST only |
|
||||
| lambdas.cpp:8:10:8:15 | lambdas.cpp:21:3:21:6 | AST only |
|
||||
|
||||
@@ -14,6 +14,9 @@
|
||||
| dispatch.cpp:11:38:11:38 | x | dispatch.cpp:45:18:45:23 | call to source |
|
||||
| dispatch.cpp:23:38:23:38 | x | dispatch.cpp:33:18:33:23 | call to source |
|
||||
| dispatch.cpp:23:38:23:38 | x | dispatch.cpp:41:17:41:22 | call to source |
|
||||
| dispatch.cpp:23:38:23:38 | x | dispatch.cpp:69:15:69:20 | call to source |
|
||||
| dispatch.cpp:23:38:23:38 | x | dispatch.cpp:73:14:73:19 | call to source |
|
||||
| dispatch.cpp:23:38:23:38 | x | dispatch.cpp:81:13:81:18 | call to source |
|
||||
| dispatch.cpp:31:16:31:24 | call to isSource1 | dispatch.cpp:22:37:22:42 | call to source |
|
||||
| dispatch.cpp:32:16:32:24 | call to isSource2 | dispatch.cpp:16:37:16:42 | call to source |
|
||||
| dispatch.cpp:35:16:35:25 | call to notSource1 | dispatch.cpp:9:37:9:42 | call to source |
|
||||
@@ -22,6 +25,9 @@
|
||||
| dispatch.cpp:40:15:40:23 | call to isSource2 | dispatch.cpp:16:37:16:42 | call to source |
|
||||
| dispatch.cpp:43:15:43:24 | call to notSource1 | dispatch.cpp:9:37:9:42 | call to source |
|
||||
| dispatch.cpp:44:15:44:24 | call to notSource2 | dispatch.cpp:10:37:10:42 | call to source |
|
||||
| dispatch.cpp:55:22:55:30 | call to isSource1 | dispatch.cpp:22:37:22:42 | call to source |
|
||||
| dispatch.cpp:58:28:58:36 | call to isSource1 | dispatch.cpp:22:37:22:42 | call to source |
|
||||
| dispatch.cpp:96:8:96:8 | x | dispatch.cpp:107:17:107:22 | call to source |
|
||||
| test.cpp:7:8:7:9 | t1 | test.cpp:6:12:6:17 | call to source |
|
||||
| test.cpp:9:8:9:9 | t1 | test.cpp:6:12:6:17 | call to source |
|
||||
| test.cpp:10:8:10:9 | t2 | test.cpp:6:12:6:17 | call to source |
|
||||
|
||||
Reference in New Issue
Block a user