Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions cpp/ql/lib/change-notes/2026-01-23-as-definition.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
---
category: fix
---
* Fixed a bug which caused `Node.asDefinition()` to not have a result for certain assignments.
Original file line number Diff line number Diff line change
Expand Up @@ -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.
*
Expand Down Expand Up @@ -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
)
}

Expand Down
18 changes: 18 additions & 0 deletions cpp/ql/test/library-tests/dataflow/asDefinition/test.cpp
Original file line number Diff line number Diff line change
@@ -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; // $ asDefinition=43
x = 44; // $ asDefinition="... = ..."

S s;
s.x = 42; // $ asDefinition="... = ..."
}
Empty file.
22 changes: 22 additions & 0 deletions cpp/ql/test/library-tests/dataflow/asDefinition/test.ql
Original file line number Diff line number Diff line change
@@ -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<AsDefinitionTest>