From 9a2c1daebe2313a56e332b9f02a23f7934aec1c3 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Tue, 17 Oct 2023 11:48:44 +0100 Subject: [PATCH] C++: Add tests for 'AdditionalCallTarget'. --- .../dataflow/fields/IRConfiguration.qll | 13 +++++++++++++ .../dataflow/fields/ir-path-flow.expected | 8 ++++++++ .../library-tests/dataflow/fields/simple.cpp | 17 +++++++++++++++++ 3 files changed, 38 insertions(+) diff --git a/cpp/ql/test/library-tests/dataflow/fields/IRConfiguration.qll b/cpp/ql/test/library-tests/dataflow/fields/IRConfiguration.qll index 494d15efb9c..9a30be4f9d9 100644 --- a/cpp/ql/test/library-tests/dataflow/fields/IRConfiguration.qll +++ b/cpp/ql/test/library-tests/dataflow/fields/IRConfiguration.qll @@ -1,6 +1,19 @@ private import semmle.code.cpp.ir.dataflow.DataFlow private import DataFlow +private class TestAdditionalCallTarget extends AdditionalCallTarget { + override Function viableTarget(Call call) { + // To test that call targets specified by `AdditionalCallTarget` are + // resolved correctly this subclass resolves all calls to + // `call_template_argument(x)` as if the user had written `f(x)`. + exists(FunctionTemplateInstantiation inst | + inst.getTemplate().hasName("call_template_argument") and + call.getTarget() = inst and + result = inst.getTemplateArgument(0).(FunctionAccess).getTarget() + ) + } +} + module IRConfig implements ConfigSig { predicate isSource(Node src) { src.asExpr() instanceof NewExpr diff --git a/cpp/ql/test/library-tests/dataflow/fields/ir-path-flow.expected b/cpp/ql/test/library-tests/dataflow/fields/ir-path-flow.expected index 9c30be7684a..f6284e9713a 100644 --- a/cpp/ql/test/library-tests/dataflow/fields/ir-path-flow.expected +++ b/cpp/ql/test/library-tests/dataflow/fields/ir-path-flow.expected @@ -770,6 +770,9 @@ edges | simple.cpp:92:7:92:7 | a indirection [post update] [i] | simple.cpp:94:10:94:11 | a2 indirection [i] | | simple.cpp:92:11:92:20 | call to user_input | simple.cpp:92:5:92:22 | ... = ... | | simple.cpp:94:10:94:11 | a2 indirection [i] | simple.cpp:94:13:94:13 | i | +| simple.cpp:103:24:103:24 | x | simple.cpp:104:14:104:14 | x | +| simple.cpp:108:17:108:26 | call to user_input | simple.cpp:109:43:109:43 | x | +| simple.cpp:109:43:109:43 | x | simple.cpp:103:24:103:24 | x | | struct_init.c:14:24:14:25 | ab indirection [a] | struct_init.c:15:8:15:9 | ab indirection [a] | | struct_init.c:15:8:15:9 | ab indirection [a] | struct_init.c:15:12:15:12 | a | | struct_init.c:20:13:20:14 | definition of ab indirection [a] | struct_init.c:22:8:22:9 | ab indirection [a] | @@ -1576,6 +1579,10 @@ nodes | simple.cpp:92:11:92:20 | call to user_input | semmle.label | call to user_input | | simple.cpp:94:10:94:11 | a2 indirection [i] | semmle.label | a2 indirection [i] | | simple.cpp:94:13:94:13 | i | semmle.label | i | +| simple.cpp:103:24:103:24 | x | semmle.label | x | +| simple.cpp:104:14:104:14 | x | semmle.label | x | +| simple.cpp:108:17:108:26 | call to user_input | semmle.label | call to user_input | +| simple.cpp:109:43:109:43 | x | semmle.label | x | | struct_init.c:14:24:14:25 | ab indirection [a] | semmle.label | ab indirection [a] | | struct_init.c:15:8:15:9 | ab indirection [a] | semmle.label | ab indirection [a] | | struct_init.c:15:12:15:12 | a | semmle.label | a | @@ -1782,6 +1789,7 @@ subpaths | simple.cpp:67:13:67:13 | i | simple.cpp:65:11:65:20 | call to user_input | simple.cpp:67:13:67:13 | i | i flows from $@ | simple.cpp:65:11:65:20 | call to user_input | call to user_input | | simple.cpp:84:14:84:20 | call to getf2f1 | simple.cpp:83:17:83:26 | call to user_input | simple.cpp:84:14:84:20 | call to getf2f1 | call to getf2f1 flows from $@ | simple.cpp:83:17:83:26 | call to user_input | call to user_input | | simple.cpp:94:13:94:13 | i | simple.cpp:92:11:92:20 | call to user_input | simple.cpp:94:13:94:13 | i | i flows from $@ | simple.cpp:92:11:92:20 | call to user_input | call to user_input | +| simple.cpp:104:14:104:14 | x | simple.cpp:108:17:108:26 | call to user_input | simple.cpp:104:14:104:14 | x | x flows from $@ | simple.cpp:108:17:108:26 | call to user_input | call to user_input | | struct_init.c:15:12:15:12 | a | struct_init.c:20:20:20:29 | call to user_input | struct_init.c:15:12:15:12 | a | a flows from $@ | struct_init.c:20:20:20:29 | call to user_input | call to user_input | | struct_init.c:15:12:15:12 | a | struct_init.c:27:7:27:16 | call to user_input | struct_init.c:15:12:15:12 | a | a flows from $@ | struct_init.c:27:7:27:16 | call to user_input | call to user_input | | struct_init.c:15:12:15:12 | a | struct_init.c:40:20:40:29 | call to user_input | struct_init.c:15:12:15:12 | a | a flows from $@ | struct_init.c:40:20:40:29 | call to user_input | call to user_input | diff --git a/cpp/ql/test/library-tests/dataflow/fields/simple.cpp b/cpp/ql/test/library-tests/dataflow/fields/simple.cpp index e4d4f70edb0..36756689855 100644 --- a/cpp/ql/test/library-tests/dataflow/fields/simple.cpp +++ b/cpp/ql/test/library-tests/dataflow/fields/simple.cpp @@ -94,4 +94,21 @@ void single_field_test_typedef(A_typedef a) sink(a2.i); //$ ast,ir } +namespace TestAdditionalCallTargets { + + using TakesIntReturnsVoid = void(*)(int); + template + void call_template_argument(int); + + void call_sink(int x) { + sink(x); // $ ir + } + + void test_additional_call_targets() { + int x = user_input(); + call_template_argument(x); + } + +} + } // namespace Simple