From e58a8330cd263ef0053f8f4fe58180fcdf2ffde2 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Fri, 23 Jan 2026 16:19:06 +0000 Subject: [PATCH 1/3] C++: Add test for asDefinition. --- .../dataflow/asDefinition/test.cpp | 18 +++++++++++++++ .../dataflow/asDefinition/test.expected | 0 .../dataflow/asDefinition/test.ql | 22 +++++++++++++++++++ 3 files changed, 40 insertions(+) create mode 100644 cpp/ql/test/library-tests/dataflow/asDefinition/test.cpp create mode 100644 cpp/ql/test/library-tests/dataflow/asDefinition/test.expected create mode 100644 cpp/ql/test/library-tests/dataflow/asDefinition/test.ql diff --git a/cpp/ql/test/library-tests/dataflow/asDefinition/test.cpp b/cpp/ql/test/library-tests/dataflow/asDefinition/test.cpp new file mode 100644 index 000000000000..6af97c18b150 --- /dev/null +++ b/cpp/ql/test/library-tests/dataflow/asDefinition/test.cpp @@ -0,0 +1,18 @@ +struct S { + int x; +}; + +void use(int); + +void test() { + int y = 43; // $ asDefinition=43 + use(y); + y = 44; // $ asDefinition="... = ..." + use(y); + + int x = 43; // $ MISSING: asDefinition=43 + x = 44; // $ MISSING: asDefinition="... = ..." + + S s; + s.x = 42; // $ MISSING: asDefinition="... = ..." +} \ No newline at end of file diff --git a/cpp/ql/test/library-tests/dataflow/asDefinition/test.expected b/cpp/ql/test/library-tests/dataflow/asDefinition/test.expected new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/cpp/ql/test/library-tests/dataflow/asDefinition/test.ql b/cpp/ql/test/library-tests/dataflow/asDefinition/test.ql new file mode 100644 index 000000000000..b996f47fb49f --- /dev/null +++ b/cpp/ql/test/library-tests/dataflow/asDefinition/test.ql @@ -0,0 +1,22 @@ +import cpp +import utils.test.InlineExpectationsTest +import semmle.code.cpp.dataflow.new.DataFlow::DataFlow + +bindingset[s] +string quote(string s) { if s.matches("% %") then result = "\"" + s + "\"" else result = s } + +module AsDefinitionTest implements TestSig { + string getARelevantTag() { result = "asDefinition" } + + predicate hasActualResult(Location location, string element, string tag, string value) { + exists(Node n, Expr e | + e = n.asDefinition() and + location = e.getLocation() and + element = n.toString() and + tag = "asDefinition" and + value = quote(e.toString()) + ) + } +} + +import MakeTest From a556152b9d2b60c7c804dcc45329d09587595410 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Fri, 23 Jan 2026 16:23:21 +0000 Subject: [PATCH 2/3] C++: Fix asDefinition to not only work for SSA definitions. --- .../code/cpp/ir/dataflow/internal/DataFlowUtil.qll | 12 +++++++++--- .../library-tests/dataflow/asDefinition/test.cpp | 6 +++--- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowUtil.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowUtil.qll index 1c338d5a52d9..c66c76e60d78 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowUtil.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowUtil.qll @@ -312,6 +312,13 @@ class Node extends TIRDataFlowNode { */ Expr asDefinition() { result = this.asDefinition(_) } + private predicate isCertainStore() { + exists(SsaImpl::Definition def | + SsaImpl::defToNode(this, def, _) and + def.isCertain() + ) + } + /** * Gets the definition associated with this node, if any. * @@ -361,11 +368,10 @@ class Node extends TIRDataFlowNode { * pointed to by `p`. */ Expr asDefinition(boolean uncertain) { - exists(StoreInstruction store, SsaImpl::Definition def | + exists(StoreInstruction store | store = this.asInstruction() and result = asDefinitionImpl(store) and - SsaImpl::defToNode(this, def, _) and - if def.isCertain() then uncertain = false else uncertain = true + if this.isCertainStore() then uncertain = false else uncertain = true ) } diff --git a/cpp/ql/test/library-tests/dataflow/asDefinition/test.cpp b/cpp/ql/test/library-tests/dataflow/asDefinition/test.cpp index 6af97c18b150..facb67399585 100644 --- a/cpp/ql/test/library-tests/dataflow/asDefinition/test.cpp +++ b/cpp/ql/test/library-tests/dataflow/asDefinition/test.cpp @@ -10,9 +10,9 @@ void test() { y = 44; // $ asDefinition="... = ..." use(y); - int x = 43; // $ MISSING: asDefinition=43 - x = 44; // $ MISSING: asDefinition="... = ..." + int x = 43; // $ asDefinition=43 + x = 44; // $ asDefinition="... = ..." S s; - s.x = 42; // $ MISSING: asDefinition="... = ..." + s.x = 42; // $ asDefinition="... = ..." } \ No newline at end of file From 6c2a3a68b6b82c793cbdfcd69de394ea0a309193 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Fri, 23 Jan 2026 16:35:02 +0000 Subject: [PATCH 3/3] C++: Add change note. --- cpp/ql/lib/change-notes/2026-01-23-as-definition.md | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 cpp/ql/lib/change-notes/2026-01-23-as-definition.md diff --git a/cpp/ql/lib/change-notes/2026-01-23-as-definition.md b/cpp/ql/lib/change-notes/2026-01-23-as-definition.md new file mode 100644 index 000000000000..1f18562cdcd7 --- /dev/null +++ b/cpp/ql/lib/change-notes/2026-01-23-as-definition.md @@ -0,0 +1,4 @@ +--- +category: fix +--- +* Fixed a bug which caused `Node.asDefinition()` to not have a result for certain assignments. \ No newline at end of file