This revision was automatically updated to reflect the committed changes.
Closed by commit rC347943: [analyzer] Add the type of the leaked object to the 
diagnostic message (authored by george.karpenkov, committed by ).
Herald added a subscriber: cfe-commits.

Changed prior to commit:
  https://reviews.llvm.org/D55033?vs=176005&id=176012#toc

Repository:
  rC Clang

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D55033/new/

https://reviews.llvm.org/D55033

Files:
  lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp
  lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.h
  test/Analysis/Inputs/expected-plists/objc-arc.m.plist
  test/Analysis/Inputs/expected-plists/retain-release-path-notes.m.plist
  test/Analysis/objc-radar17039661.m
  test/Analysis/osobject-retain-release.cpp
  test/Analysis/retain-release-path-notes.m
  test/Analysis/retaincountchecker-compoundregion.m

Index: lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.h
===================================================================
--- lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.h
+++ lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.h
@@ -141,12 +141,14 @@
 };
 
 class CFRefReport : public BugReport {
+protected:
+  SymbolRef Sym;
 
 public:
   CFRefReport(CFRefBug &D, const LangOptions &LOpts,
               const SummaryLogTy &Log, ExplodedNode *n, SymbolRef sym,
               bool registerVisitor = true)
-    : BugReport(D, D.getDescription(), n) {
+    : BugReport(D, D.getDescription(), n), Sym(sym) {
     if (registerVisitor)
       addVisitor(llvm::make_unique<CFRefReportVisitor>(sym, Log));
   }
Index: lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp
===================================================================
--- lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp
+++ lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp
@@ -28,6 +28,17 @@
          isa<CXXBoolLiteralExpr>(E);
 }
 
+/// If type represents a pointer to CXXRecordDecl,
+/// and is not a typedef, return the decl name.
+/// Otherwise, return the serialization of type.
+static StringRef getPrettyTypeName(QualType QT) {
+  QualType PT = QT->getPointeeType();
+  if (!PT.isNull() && !QT->getAs<TypedefType>())
+    if (const auto *RD = PT->getAsCXXRecordDecl())
+      return RD->getName();
+  return QT.getAsString();
+}
+
 /// Write information about the type state change to {@code os},
 /// return whether the note should be generated.
 static bool shouldGenerateNote(llvm::raw_string_ostream &os,
@@ -193,7 +204,7 @@
            << Sym->getType().getAsString() << " with a ";
       } else if (CurrV.getObjKind() == RetEffect::OS) {
         os << " returns an OSObject of type "
-           << Sym->getType().getAsString() << " with a ";
+           << getPrettyTypeName(Sym->getType()) << " with a ";
       } else if (CurrV.getObjKind() == RetEffect::Generalized) {
         os << " returns an object of type " << Sym->getType().getAsString()
            << " with a ";
@@ -432,7 +443,7 @@
   if (RegionDescription) {
     os << "object allocated and stored into '" << *RegionDescription << '\'';
   } else {
-    os << "allocated object";
+    os << "allocated object of type " << getPrettyTypeName(Sym->getType());
   }
 
   // Get the retain count.
@@ -472,10 +483,10 @@
               " Foundation";
       }
     }
-  }
-  else
+  } else {
     os << " is not referenced later in this execution path and has a retain "
           "count of +" << RV->getCount();
+  }
 
   return std::make_shared<PathDiagnosticEventPiece>(L, os.str());
 }
@@ -555,6 +566,10 @@
       FullSourceLoc SL(AllocStmt->getBeginLoc(), Ctx.getSourceManager());
       os << " (allocated on line " << SL.getSpellingLineNumber() << ")";
     }
+  } else {
+
+    // If we can't figure out the name, just supply the type information.
+    os << " of type " << getPrettyTypeName(Sym->getType());
   }
 }
 
Index: test/Analysis/retain-release-path-notes.m
===================================================================
--- test/Analysis/retain-release-path-notes.m
+++ test/Analysis/retain-release-path-notes.m
@@ -227,7 +227,7 @@
                                 // expected-note@-1 {{Method returns an instance of MyObj with a +1 retain count}}
                                 // expected-note@-2 {{Calling 'initX'}}
                                 // expected-note@-3 {{Returning from 'initX'}}
-                                // expected-note@-4 {{Object leaked: allocated object is not referenced later in this execution path and has a retain count of +1}}
+                                // expected-note@-4 {{Object leaked: allocated object of type MyObj * is not referenced later in this execution path and has a retain count of +1}}
   // initI is inlined because the allocation happens within initY
   id y = [[MyObj alloc] initY];
                                 // expected-note@-1 {{Calling 'initY'}}
Index: test/Analysis/osobject-retain-release.cpp
===================================================================
--- test/Analysis/osobject-retain-release.cpp
+++ test/Analysis/osobject-retain-release.cpp
@@ -61,13 +61,13 @@
 }
 
 void check_no_invalidation() {
-  OSArray *arr = OSArray::withCapacity(10); // expected-note{{Call to function 'withCapacity' returns an OSObject of type struct OSArray * with a +1 retain count}}
+  OSArray *arr = OSArray::withCapacity(10); // expected-note{{Call to function 'withCapacity' returns an OSObject of type OSArray with a +1 retain count}}
   OtherStruct::doNothingToArray(arr);
 } // expected-warning{{Potential leak of an object stored into 'arr'}}
   // expected-note@-1{{Object leaked}}
 
 void check_no_invalidation_other_struct() {
-  OSArray *arr = OSArray::withCapacity(10); // expected-note{{Call to function 'withCapacity' returns an OSObject of type struct OSArray * with a +1 retain count}}
+  OSArray *arr = OSArray::withCapacity(10); // expected-note{{Call to function 'withCapacity' returns an OSObject of type OSArray with a +1 retain count}}
   OtherStruct other(arr); // expected-warning{{Potential leak}}
                           // expected-note@-1{{Object leaked}}
 }
@@ -94,7 +94,8 @@
 };
 
 OSArray *generateArray() {
-  return OSArray::withCapacity(10); // expected-note{{Call to function 'withCapacity' returns an OSObject of type struct OSArray * with a +1 retain count}}
+  return OSArray::withCapacity(10); // expected-note{{Call to function 'withCapacity' returns an OSObject of type OSArray with a +1 retain count}}
+                                    // expected-note@-1{{Call to function 'withCapacity' returns an OSObject of type OSArray with a +1 retain count}}
 }
 
 unsigned int check_leak_good_error_message() {
@@ -109,7 +110,10 @@
 }
 
 unsigned int check_leak_msg_temporary() {
-  return generateArray()->getCount();
+  return generateArray()->getCount(); // expected-warning{{Potential leak of an object}}
+                                      // expected-note@-1{{Calling 'generateArray'}}
+                                      // expected-note@-2{{Returning from 'generateArray'}}
+                                      // expected-note@-3{{Object leaked: allocated object of type OSArray is not referenced later in this execution path and has a retain count of +1}}
 }
 
 void check_confusing_getters() {
@@ -178,14 +182,14 @@
 }
 
 void use_after_release() {
-  OSArray *arr = OSArray::withCapacity(10); // expected-note{{Call to function 'withCapacity' returns an OSObject of type struct OSArray * with a +1 retain count}}
+  OSArray *arr = OSArray::withCapacity(10); // expected-note{{Call to function 'withCapacity' returns an OSObject of type OSArray with a +1 retain count}}
   arr->release(); // expected-note{{Object released}}
   arr->getCount(); // expected-warning{{Reference-counted object is used after it is released}}
                    // expected-note@-1{{Reference-counted object is used after it is released}}
 }
 
 void potential_leak() {
-  OSArray *arr = OSArray::withCapacity(10); // expected-note{{Call to function 'withCapacity' returns an OSObject of type struct OSArray * with a +1 retain count}}
+  OSArray *arr = OSArray::withCapacity(10); // expected-note{{Call to function 'withCapacity' returns an OSObject of type OSArray with a +1 retain count}}
   arr->retain(); // expected-note{{Reference count incremented. The object now has a +2 retain count}}
   arr->release(); // expected-note{{Reference count decremented. The object now has a +1 retain count}}
   arr->getCount();
@@ -236,7 +240,7 @@
 }
 
 unsigned int warn_on_overrelease_with_unknown_source(ArrayOwner *owner) {
-  OSArray *arr = owner->getArraySourceUnknown(); // expected-note{{function call returns an OSObject of type struct OSArray * with a +0 retain count}}
+  OSArray *arr = owner->getArraySourceUnknown(); // expected-note{{function call returns an OSObject of type OSArray with a +0 retain count}}
   arr->release(); // expected-warning{{Incorrect decrement of the reference count of an object that is not owned at this point by the caller}}
                   // expected-note@-1{{Incorrect decrement of the reference count of an object that is not owned at this point by the caller}}
   return arr->getCount();
Index: test/Analysis/retaincountchecker-compoundregion.m
===================================================================
--- test/Analysis/retaincountchecker-compoundregion.m
+++ test/Analysis/retaincountchecker-compoundregion.m
@@ -19,7 +19,7 @@
   int width = 0;
   int height = 0;
   CFTypeRef* values = (CFTypeRef[]){
-    CFNumberCreate(allocator, kCFNumberSInt32Type, &width), //expected-warning-re{{Potential leak of an object{{$}}}}
-    CFNumberCreate(allocator, kCFNumberSInt32Type, &height), //expected-warning-re{{Potential leak of an object{{$}}}}
+    CFNumberCreate(allocator, kCFNumberSInt32Type, &width), //expected-warning{{Potential leak of an object of type CFNumberRef}}
+    CFNumberCreate(allocator, kCFNumberSInt32Type, &height), //expected-warning{{Potential leak of an object of type CFNumberRef}}
   };
 }
Index: test/Analysis/objc-radar17039661.m
===================================================================
--- test/Analysis/objc-radar17039661.m
+++ test/Analysis/objc-radar17039661.m
@@ -1315,12 +1315,12 @@
 // CHECK:     </array>
 // CHECK:     <key>depth</key><integer>4</integer>
 // CHECK:     <key>extended_message</key>
-// CHECK:     <string>Object leaked: allocated object is not referenced later in this execution path and has a retain count of +1</string>
+// CHECK:     <string>Object leaked: allocated object of type NSNumber * is not referenced later in this execution path and has a retain count of +1</string>
 // CHECK:     <key>message</key>
-// CHECK:     <string>Object leaked: allocated object is not referenced later in this execution path and has a retain count of +1</string>
+// CHECK:     <string>Object leaked: allocated object of type NSNumber * is not referenced later in this execution path and has a retain count of +1</string>
 // CHECK:    </dict>
 // CHECK:   </array>
-// CHECK:   <key>description</key><string>Potential leak of an object</string>
+// CHECK:   <key>description</key><string>Potential leak of an object of type NSNumber *</string>
 // CHECK:   <key>category</key><string>Memory (Core Foundation/Objective-C)</string>
 // CHECK:   <key>type</key><string>Leak</string>
 // CHECK:  <key>location</key>
Index: test/Analysis/Inputs/expected-plists/objc-arc.m.plist
===================================================================
--- test/Analysis/Inputs/expected-plists/objc-arc.m.plist
+++ test/Analysis/Inputs/expected-plists/objc-arc.m.plist
@@ -1727,12 +1727,12 @@
      </dict>
      <key>depth</key><integer>0</integer>
      <key>extended_message</key>
-     <string>Object leaked: allocated object is not referenced later in this execution path and has a retain count of +1</string>
+     <string>Object leaked: allocated object of type CFStringRef is not referenced later in this execution path and has a retain count of +1</string>
      <key>message</key>
-     <string>Object leaked: allocated object is not referenced later in this execution path and has a retain count of +1</string>
+     <string>Object leaked: allocated object of type CFStringRef is not referenced later in this execution path and has a retain count of +1</string>
     </dict>
    </array>
-   <key>description</key><string>Potential leak of an object</string>
+   <key>description</key><string>Potential leak of an object of type CFStringRef</string>
    <key>category</key><string>Memory (Core Foundation/Objective-C)</string>
    <key>type</key><string>Leak</string>
    <key>check_name</key><string>osx.cocoa.RetainCount</string>
Index: test/Analysis/Inputs/expected-plists/retain-release-path-notes.m.plist
===================================================================
--- test/Analysis/Inputs/expected-plists/retain-release-path-notes.m.plist
+++ test/Analysis/Inputs/expected-plists/retain-release-path-notes.m.plist
@@ -3834,12 +3834,12 @@
      </array>
      <key>depth</key><integer>0</integer>
      <key>extended_message</key>
-     <string>Object leaked: allocated object is not referenced later in this execution path and has a retain count of +1</string>
+     <string>Object leaked: allocated object of type MyObj * is not referenced later in this execution path and has a retain count of +1</string>
      <key>message</key>
-     <string>Object leaked: allocated object is not referenced later in this execution path and has a retain count of +1</string>
+     <string>Object leaked: allocated object of type MyObj * is not referenced later in this execution path and has a retain count of +1</string>
     </dict>
    </array>
-   <key>description</key><string>Potential leak of an object</string>
+   <key>description</key><string>Potential leak of an object of type MyObj *</string>
    <key>category</key><string>Memory (Core Foundation/Objective-C)</string>
    <key>type</key><string>Leak</string>
    <key>check_name</key><string>osx.cocoa.RetainCount</string>
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to