vsavchenko created this revision. vsavchenko added reviewers: NoQ, xazax.hun, jkorous, aaron.ballman, martong, Szelethus, steakhal. Herald added subscribers: Charusso, rnkovacs. vsavchenko requested review of this revision. Herald added a project: clang. Herald added a subscriber: cfe-commits.
In addition to the actual bug location, we can check if the uniqueing location has user-provided suppressions. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D94177 Files: clang/include/clang/StaticAnalyzer/Core/BugReporter/BugSuppression.h clang/lib/StaticAnalyzer/Core/BugReporter.cpp clang/lib/StaticAnalyzer/Core/BugSuppression.cpp clang/test/Analysis/suppression-attr.m
Index: clang/test/Analysis/suppression-attr.m =================================================================== --- clang/test/Analysis/suppression-attr.m +++ clang/test/Analysis/suppression-attr.m @@ -4,6 +4,7 @@ // RUN: -analyzer-checker=osx.cocoa.NSError \ // RUN: -analyzer-checker=osx.ObjCProperty \ // RUN: -analyzer-checker=osx.cocoa.RetainCount \ +// RUN: -analyzer-checker=unix.Malloc \ // RUN: -analyzer-checker=alpha.core.CastToStruct \ // RUN: -Wno-unused-value -Wno-objc-root-class -verify %s @@ -37,6 +38,10 @@ @interface NSMutableString : NSObject @end +typedef unsigned long size_t; +void *malloc(size_t); +void free(void *); + void dereference_1() { int *x = 0; *x; // expected-warning{{Dereference of null pointer (loaded from variable 'x')}} @@ -83,6 +88,50 @@ SUPPRESS int y = *x; // no-warning } +int malloc_leak_1() { + int *x = (int *)malloc(sizeof(int)); + *x = 42; + return *x; // expected-warning{{Potential leak of memory pointed to by 'x'}} +} + +int malloc_leak_suppression_1_1() { + SUPPRESS int *x = (int *)malloc(sizeof(int)); + *x = 42; + return *x; +} + +int malloc_leak_suppression_1_2() { + int *x = (int *)malloc(sizeof(int)); + *x = 42; + SUPPRESS return *x; +} + +void malloc_leak_2() { + int *x = (int *)malloc(sizeof(int)); + *x = 42; +} // expected-warning{{Potential leak of memory pointed to by 'x'}} + +void malloc_leak_suppression_2_1() { + SUPPRESS int *x = (int *)malloc(sizeof(int)); + *x = 42; +} + +void malloc_leak_suppression_2_2() SUPPRESS { + int *x = (int *)malloc(sizeof(int)); + *x = 42; +} + +SUPPRESS void malloc_leak_suppression_2_3() { + int *x = (int *)malloc(sizeof(int)); + *x = 42; +} + +void malloc_leak_suppression_2_4(int cond) { + int *x = (int *)malloc(sizeof(int)); + *x = 42; + SUPPRESS; +} + void retain_release_leak_1() { [[NSMutableString alloc] init]; // expected-warning{{Potential leak of an object of type 'NSMutableString *'}} } Index: clang/lib/StaticAnalyzer/Core/BugSuppression.cpp =================================================================== --- clang/lib/StaticAnalyzer/Core/BugSuppression.cpp +++ clang/lib/StaticAnalyzer/Core/BugSuppression.cpp @@ -132,8 +132,15 @@ // (i.e. removing the whole function from the analysis). bool BugSuppression::isSuppressed(const BugReport &R) { PathDiagnosticLocation Location = R.getLocation(); + PathDiagnosticLocation UniqueingLocation = R.getUniqueingLocation(); const Decl *DeclWithIssue = R.getDeclWithIssue(); + return isSuppressed(Location, DeclWithIssue) || + isSuppressed(UniqueingLocation, DeclWithIssue); +} + +bool BugSuppression::isSuppressed(const PathDiagnosticLocation &Location, + const Decl *DeclWithIssue) { if (!Location.isValid() || DeclWithIssue == nullptr) return false; Index: clang/lib/StaticAnalyzer/Core/BugReporter.cpp =================================================================== --- clang/lib/StaticAnalyzer/Core/BugReporter.cpp +++ clang/lib/StaticAnalyzer/Core/BugReporter.cpp @@ -2386,11 +2386,10 @@ return Ranges; } -PathDiagnosticLocation -PathSensitiveBugReport::getLocation() const { +PathDiagnosticLocation PathSensitiveBugReport::getLocation() const { assert(ErrorNode && "Cannot create a location with a null node."); const Stmt *S = ErrorNode->getStmtForDiagnostics(); - ProgramPoint P = ErrorNode->getLocation(); + ProgramPoint P = ErrorNode->getLocation(); const LocationContext *LC = P.getLocationContext(); SourceManager &SM = ErrorNode->getState()->getStateManager().getContext().getSourceManager(); @@ -2407,6 +2406,12 @@ } if (S) { + // Attributed statements usually have corrupted begin locations, + // it's OK to ignore attributes for our purposes and deal with + // the actual annotated statement. + if (const auto *AS = dyn_cast<AttributedStmt>(S)) + S = AS->getSubStmt(); + // For member expressions, return the location of the '.' or '->'. if (const auto *ME = dyn_cast<MemberExpr>(S)) return PathDiagnosticLocation::createMemberLoc(ME, SM); Index: clang/include/clang/StaticAnalyzer/Core/BugReporter/BugSuppression.h =================================================================== --- clang/include/clang/StaticAnalyzer/Core/BugReporter/BugSuppression.h +++ clang/include/clang/StaticAnalyzer/Core/BugReporter/BugSuppression.h @@ -23,11 +23,16 @@ namespace ento { class BugReport; +class PathDiagnosticLocation; class BugSuppression { public: /// Return true if the given bug report was explicitly suppressed by the user. bool isSuppressed(const BugReport &); + /// Return true if the bug reported at the given location was explicitly + /// suppressed by the user. + bool isSuppressed(const PathDiagnosticLocation &Location, + const Decl *DeclWithIssue); private: // Overly pessimistic number, to be honest.
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits