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
  • [PATCH] D94177: [analyze... Valeriy Savchenko via Phabricator via cfe-commits

Reply via email to