C++: Fix missing results for Node.asDefinition#21212
Conversation
There was a problem hiding this comment.
Pull request overview
Fixes DataFlow::Node.asDefinition so it returns a result (marked uncertain = true) even when the underlying StoreInstruction has no corresponding SSA definition, preventing “missing result” cases.
Changes:
- Adjusted
Node.asDefinition/1implementation to avoid depending onSsaImpl::defToNodefor producing any result. - Added a new InlineExpectations-based regression test for
asDefinitionover different store forms (including a field store / dead variable store).
Reviewed changes
Copilot reviewed 4 out of 5 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowUtil.qll | Updates asDefinition uncertainty determination so stores without SSA still yield a result. |
| cpp/ql/test/library-tests/dataflow/asDefinition/test.ql | Adds an InlineExpectations test query for Node.asDefinition. |
| cpp/ql/test/library-tests/dataflow/asDefinition/test.cpp | Adds C++ test cases exercising assignments/initializers including a field store. |
| cpp/ql/test/library-tests/dataflow/asDefinition/test.expected | Empty InlineExpectations expected-output file for the new test. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
Could you explain why |
It's basically the sound choice. Notice this part of the QLDoc (emphasis mine) from this predicate:
In order words, the |
|
Thanks. In the case you're handling here there are effectively no paths, if I understand correctly, so wouldn't |
|
We're handling that we couldn't conclude whether we know about all the paths. Consider something like this (which is outside the scope of the C/C++ SSA since we don't have field-based SSA): void foo(int**);
struct S {
int* p;
};
S s;
foo(&s.p);
*s.p = 42;When we reach S s;
foo(&s.p);
*s.p = source();
... // (1)
*s.p = 42;
... // (2)
sink(*s.p);On main we don't have a result for When |
|
Thanks for the explanation. That makes sense. |
|
DCA was uneventful 🎉 |
* C++: Add test for asDefinition. * C++: Fix asDefinition to not only work for SSA definitions.
For a dataflow node
none can ask ifnis the node corresponding to aStoreInstruction. This is useful when one wants to deal uniformly with all kinds of assignments/initializers/increments/decrements/etc.The predicate also tells you whether an assignment overwrites an entire buffer or whether it may be a partial write (i.e.,
node.asDefinition(true)means the write may not overwrite the entire buffer). In order to do that it uses some of the SSA predicates (in particular,SsaImpl::defToNode) to find the correspondingSsa::Definitionbelonging to theStoreInstruction.However, if there's no corresponding SSA information for the
StoreInstruction(for instance, if it's a store to a field or to a variable that is not live) thenSsaImpl::defToNodewon't hold. And so the entirenode.asDefinitionpredicate did not have a result.This PR fixes this so that, instead of the predicate not having a result, it will have a result with
uncertain = true. This means thatnode.asDefinitioncan now be used to grab all assignments/initializers/increments/decrements/etc regardless of whether we have SSA information for it.cc @bdrodes