Skip to content

Commit 1b41bae

Browse files
committed
C++: Add tests with missing flow.
In the upcoming commits we will add a new extensional predicate which allows us to model that a function forwards it arguments to the constructor of a given type. This initial commit adds the test YAML models for this new extensional predicate.
1 parent f7caf55 commit 1b41bae

6 files changed

Lines changed: 110 additions & 0 deletions

File tree

‎cpp/ql/lib/ext/empty.model.yml‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,3 +21,7 @@ extensions:
2121
pack: codeql/cpp-all
2222
extensible: summaryModel
2323
data: []
24+
- addsTo:
25+
pack: codeql/cpp-all
26+
extensible: forwardsModel
27+
data: []

‎cpp/ql/lib/semmle/code/cpp/dataflow/internal/ExternalFlowExtensions.qll‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,14 @@ extensible predicate neutralModel(
5151
string namespace, string type, string name, string signature, string kind, string provenance
5252
);
5353

54+
/**
55+
* Holds if a constructor forwarding model exists for the given parameters.
56+
*/
57+
extensible predicate forwardsModel(
58+
string namespace, string type, boolean subtypes, string name, string signature, string ext,
59+
string start, string constructor, string output, string provenance, QlBuiltins::ExtensionId madId
60+
);
61+
5462
module Extensions implements SharedMaD::ExtensionsSig {
5563
import ExternalFlowExtensions
5664

‎cpp/ql/test/library-tests/dataflow/external-models/flow.ext.yml‎

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,3 +42,13 @@ extensions:
4242
- ["", "ReverseFlow", True, "get_ptr", "", "", "ReturnValue[*]", "Argument[-1].Field[ReverseFlow::value]", "value", "manual"]
4343
- ["", "MyString", True, "operator[]", "", "", "ReturnValue[*]", "Argument[-1]", "taint", "manual"]
4444
- ["", "MyString", True, "operator[]", "", "", "Argument[-1]", "ReturnValue[*]", "taint", "manual"]
45+
- ["", "Forwarder", True, "get", "", "", "Argument[-1]", "ReturnValue", "value", "manual"]
46+
- ["", "Container", True, "get", "", "", "Argument[-1].Element", "ReturnValue[*]", "value", "manual"]
47+
- ["", "Element", True, "Element", "", "", "Argument[0]", "Argument[-1].Field[Element::x]", "value", "manual"]
48+
- ["", "ElementWithDefaultArgument", True, "ElementWithDefaultArgument", "", "", "Argument[0]", "Argument[-1].Field[ElementWithDefaultArgument::x]", "value", "manual"]
49+
- addsTo:
50+
pack: codeql/cpp-all
51+
extensible: forwardsModel
52+
data: # namespace, type, subtypes, name, signature, ext, start, constructor, output, provenance
53+
- ["", "Forwarder<T>", True, "forward<Args>", "(Args &&)", "", "0", "T", "Argument[-1]", "manual"]
54+
- ["", "Container<T>", True, "emplace<Args>", "(int,Args &&)", "", "1", "T", "Argument[-1].Element", "manual"]

‎cpp/ql/test/library-tests/dataflow/external-models/sinks.expected‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,3 +43,9 @@
4343
| test.cpp:331:10:331:19 | * ... | test-sink |
4444
| test.cpp:333:15:333:20 | source | test-sink |
4545
| test.cpp:334:10:334:16 | * ... | test-sink |
46+
| test.cpp:365:15:365:15 | s | test-sink |
47+
| test.cpp:366:15:366:16 | ul | test-sink |
48+
| test.cpp:374:15:374:15 | s | test-sink |
49+
| test.cpp:375:15:375:16 | ul | test-sink |
50+
| test.cpp:398:13:398:13 | x | test-sink |
51+
| test.cpp:412:13:412:13 | x | test-sink |

‎cpp/ql/test/library-tests/dataflow/external-models/sources.expected‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,10 @@
1919
| test.cpp:222:10:222:18 | call to ymlSource | local |
2020
| test.cpp:297:33:297:41 | call to ymlSource | local |
2121
| test.cpp:317:51:317:59 | call to ymlSource | local |
22+
| test.cpp:361:15:361:23 | call to ymlSource | local |
23+
| test.cpp:370:24:370:32 | call to ymlSource | local |
24+
| test.cpp:394:11:394:19 | call to ymlSource | local |
25+
| test.cpp:408:11:408:19 | call to ymlSource | local |
2226
| windows.cpp:22:15:22:29 | call to GetCommandLineA | local |
2327
| windows.cpp:34:17:34:38 | call to GetEnvironmentStringsA | local |
2428
| windows.cpp:39:36:39:38 | GetEnvironmentVariableA output argument | local |

‎cpp/ql/test/library-tests/dataflow/external-models/test.cpp‎

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -332,4 +332,82 @@ void test_parameter(SourceWrapper* p, SourceWrapper s, int* source) {
332332

333333
ymlSink((int)source); // clean
334334
ymlSink(*source); // $ ir
335+
}
336+
337+
338+
struct ConstructableFromInt {
339+
short s;
340+
unsigned long ul;
341+
ConstructableFromInt(short arg) {
342+
this->s = arg;
343+
}
344+
345+
ConstructableFromInt(unsigned long arg) {
346+
this->ul = arg;
347+
}
348+
};
349+
350+
template<typename T>
351+
struct Forwarder {
352+
template<typename... Args>
353+
void forward(Args&&... args);
354+
355+
T get();
356+
};
357+
358+
void forward_test() {
359+
{
360+
Forwarder<ConstructableFromInt> f;
361+
short x = ymlSource();
362+
f.forward(x);
363+
364+
ConstructableFromInt c = f.get();
365+
ymlSink(c.s); // $ MISSING: ir
366+
ymlSink(c.ul); // clean
367+
}
368+
{
369+
Forwarder<ConstructableFromInt> f;
370+
unsigned long ul = ymlSource();
371+
f.forward(ul);
372+
373+
ConstructableFromInt c = f.get();
374+
ymlSink(c.s); // clean
375+
ymlSink(c.ul); // $ MISSING: ir
376+
}
377+
}
378+
379+
template<typename T>
380+
struct Container {
381+
template<typename... Args>
382+
void emplace(int pos, Args&&... args);
383+
384+
T& get();
385+
};
386+
387+
struct Element {
388+
int x;
389+
Element(int);
390+
};
391+
392+
void forward_test_model() {
393+
Container<Element> c;
394+
int x = ymlSource();
395+
c.emplace(0, x);
396+
397+
Element e = c.get();
398+
ymlSink(e.x); // $ MISSING: ir
399+
}
400+
401+
struct ElementWithDefaultArgument {
402+
int x;
403+
ElementWithDefaultArgument(int x, int = 0);
404+
};
405+
406+
void forward_test_model_with_default_argument() {
407+
Container<ElementWithDefaultArgument> c;
408+
int x = ymlSource();
409+
c.emplace(0, x);
410+
411+
ElementWithDefaultArgument e = c.get();
412+
ymlSink(e.x); // $ MISSING: ir
335413
}

0 commit comments

Comments
 (0)