[clang] [analyzer] Avoid out-of-order node traversal on void return (PR #117863)
Arseniy Zaostrovnykh via cfe-commits
cfe-commits at lists.llvm.org
Wed Nov 27 04:17:33 PST 2024
================
@@ -278,7 +278,9 @@ class ExplodedNode : public llvm::FoldingSetNode {
/// Useful for explaining control flow that follows the current node.
/// If the statement belongs to a body-farmed definition, retrieve the
/// call site for that definition.
- const Stmt *getNextStmtForDiagnostics() const;
+ /// If skipPurge is true, skip the purge-dead-symbols nodes (that are often
+ /// inserted out-of-order by the endinge).
+ const Stmt *getNextStmtForDiagnostics(bool skipPurge) const;
----------------
necto wrote:
I cannot speak generally, but it breaks on more test case: clang/test/Analysis/copy-elision.cpp.
In short for the following code, it moves the report further down the execution:
```C++
// RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -std=c++11 \
// RUN: -analyzer-config elide-constructors=false -DNO_ELIDE_FLAG \
// RUN: -analyzer-config eagerly-assume=false -verify=expected,no-elide %s
void clang_analyzer_eval(bool);
void clang_analyzer_dump(int);
template <typename T> struct AddressVector {
T *buf[20];
int len;
AddressVector() : len(0) {}
void push(T *t) {
buf[len] = t;
++len;
}
};
class ClassWithDestructor {
AddressVector<ClassWithDestructor> &v;
public:
ClassWithDestructor(AddressVector<ClassWithDestructor> &v) : v(v) {
push();
}
ClassWithDestructor(ClassWithDestructor &&c) : v(c.v) { push(); }
ClassWithDestructor(const ClassWithDestructor &c) : v(c.v) { push(); }
~ClassWithDestructor() { push(); }
void push() { v.push(this); }
};
struct TestCtorInitializer {
ClassWithDestructor c;
TestCtorInitializer(AddressVector<ClassWithDestructor> &v)
: c(ClassWithDestructor(v)) {} // currently: <- address of stack var leaks via 'v'
};
void testCtorInitializer() {
AddressVector<ClassWithDestructor> v;
{
TestCtorInitializer t(v); // skipping-purge: <- address of stack var leaks via 'v'
}
}
```
I.e., it ends up skipping one more stack frame.
I don't think it is a large difference, although I slightly prefer the current report to the one resulting if we skip purge always. Moreover, I wanted to reduce the test footprint, so I minimized the behavior change.
Do you think it is better simplify the logic and skip purge always?
https://github.com/llvm/llvm-project/pull/117863
More information about the cfe-commits
mailing list