[clang] [analyzer] [MallocChecker] suspect all release functions as candidate for suppression (PR #104599)
DonĂ¡t Nagy via cfe-commits
cfe-commits at lists.llvm.org
Tue Sep 3 02:42:45 PDT 2024
================
@@ -3648,35 +3652,53 @@ PathDiagnosticPieceRef MallocBugVisitor::VisitNode(const ExplodedNode *N,
return nullptr;
}
- // See if we're releasing memory while inlining a destructor
- // (or one of its callees). This turns on various common
- // false positive suppressions.
- bool FoundAnyDestructor = false;
- for (const LocationContext *LC = CurrentLC; LC; LC = LC->getParent()) {
- if (const auto *DD = dyn_cast<CXXDestructorDecl>(LC->getDecl())) {
- if (isReferenceCountingPointerDestructor(DD)) {
- // This immediately looks like a reference-counting destructor.
- // We're bad at guessing the original reference count of the object,
- // so suppress the report for now.
- BR.markInvalid(getTag(), DD);
- } else if (!FoundAnyDestructor) {
- assert(!ReleaseDestructorLC &&
- "There can be only one release point!");
- // Suspect that it's a reference counting pointer destructor.
- // On one of the next nodes might find out that it has atomic
- // reference counting operations within it (see the code above),
- // and if so, we'd conclude that it likely is a reference counting
- // pointer destructor.
- ReleaseDestructorLC = LC->getStackFrame();
- // It is unlikely that releasing memory is delegated to a destructor
- // inside a destructor of a shared pointer, because it's fairly hard
- // to pass the information that the pointer indeed needs to be
- // released into it. So we're only interested in the innermost
- // destructor.
- FoundAnyDestructor = true;
+ // Save the first destructor/function as release point.
+ assert(!ReleaseFunctionLC && "There should be only one release point");
+ ReleaseFunctionLC = CurrentLC->getStackFrame();
+
+ // See if we're releasing memory while inlining a destructor that
+ // decrement reference counters (or one of its callees).
+ // This turns on various common false positive suppressions.
+ for (const LocationContext *LC = CurrentLC; LC; LC = LC->getParent()) {
+ if (const auto *DD = dyn_cast<CXXDestructorDecl>(LC->getDecl())) {
+ if (isReferenceCountingPointerDestructor(DD)) {
+ // This immediately looks like a reference-counting destructor.
+ // We're bad at guessing the original reference count of the
+ // object, so suppress the report for now.
+ BR.markInvalid(getTag(), DD);
+
+ // After report is considered invalid there is no need to proceed
+ // futher.
+ return nullptr;
+ }
+
+ // Switch suspection to outer destructor to catch patterns like:
+ //
+ // SmartPointr::~SmartPointr() {
+ // if (__c11_atomic_fetch_sub(refcount, 1, memory_order_relaxed) ==
----------------
NagyDonat wrote:
Thanks for the update!
https://github.com/llvm/llvm-project/pull/104599
More information about the cfe-commits
mailing list