r188514 - [analyzer] Merge TextPathDiagnostics and ClangDiagPathDiagConsumer.

Jordan Rose jordan_rose at apple.com
Thu Aug 15 18:06:30 PDT 2013


Author: jrose
Date: Thu Aug 15 20:06:30 2013
New Revision: 188514

URL: http://llvm.org/viewvc/llvm-project?rev=188514&view=rev
Log:
[analyzer] Merge TextPathDiagnostics and ClangDiagPathDiagConsumer.

This once again restores notes to following their associated warnings
in -analyzer-output=text mode. (This is still only intended for use as a
debugging aid.)

One twist is that the warning locations in "regular" analysis output modes
(plist, multi-file-plist, html, and plist-html) are reported at a different
location on the command line than in the output file, since the command
line has no path context. This commit makes -analyzer-output=text behave
like a normal output format, which means that the *command line output
will be different* in -analyzer-text mode. Again, since -analyzer-text is
a debugging aid and lo-fi stand-in for a regular output mode, this change
makes sense.

Along the way, remove a few pieces of stale code related to the path
diagnostic consumers.

Added:
    cfe/trunk/test/Analysis/diagnostics/text-diagnostics.c
Removed:
    cfe/trunk/lib/StaticAnalyzer/Core/TextPathDiagnostics.cpp
Modified:
    cfe/trunk/include/clang/StaticAnalyzer/Core/Analyses.def
    cfe/trunk/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h
    cfe/trunk/include/clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h
    cfe/trunk/include/clang/StaticAnalyzer/Core/PathDiagnosticConsumers.h
    cfe/trunk/lib/Frontend/CompilerInvocation.cpp
    cfe/trunk/lib/StaticAnalyzer/Core/CMakeLists.txt
    cfe/trunk/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp
    cfe/trunk/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp
    cfe/trunk/test/Analysis/retain-release-path-notes-gc.m
    cfe/trunk/test/Analysis/retain-release-path-notes.m

Modified: cfe/trunk/include/clang/StaticAnalyzer/Core/Analyses.def
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Core/Analyses.def?rev=188514&r1=188513&r2=188514&view=diff
==============================================================================
--- cfe/trunk/include/clang/StaticAnalyzer/Core/Analyses.def (original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Core/Analyses.def Thu Aug 15 20:06:30 2013
@@ -24,14 +24,14 @@ ANALYSIS_STORE(RegionStore, "region", "U
 ANALYSIS_CONSTRAINTS(RangeConstraints, "range", "Use constraint tracking of concrete value ranges", CreateRangeConstraintManager)
 
 #ifndef ANALYSIS_DIAGNOSTICS
-#define ANALYSIS_DIAGNOSTICS(NAME, CMDFLAG, DESC, CREATEFN, AUTOCREATE)
+#define ANALYSIS_DIAGNOSTICS(NAME, CMDFLAG, DESC, CREATEFN)
 #endif
 
-ANALYSIS_DIAGNOSTICS(HTML,  "html",  "Output analysis results using HTML",   createHTMLDiagnosticConsumer, false)
-ANALYSIS_DIAGNOSTICS(PLIST, "plist", "Output analysis results using Plists", createPlistDiagnosticConsumer, true)
-ANALYSIS_DIAGNOSTICS(PLIST_MULTI_FILE, "plist-multi-file", "Output analysis results using Plists (allowing for mult-file bugs)", createPlistMultiFileDiagnosticConsumer, true)
-ANALYSIS_DIAGNOSTICS(PLIST_HTML, "plist-html", "Output analysis results using HTML wrapped with Plists", createPlistHTMLDiagnosticConsumer, true)
-ANALYSIS_DIAGNOSTICS(TEXT, "text", "Text output of analysis results", createTextPathDiagnosticConsumer, true)
+ANALYSIS_DIAGNOSTICS(HTML,  "html",  "Output analysis results using HTML",   createHTMLDiagnosticConsumer)
+ANALYSIS_DIAGNOSTICS(PLIST, "plist", "Output analysis results using Plists", createPlistDiagnosticConsumer)
+ANALYSIS_DIAGNOSTICS(PLIST_MULTI_FILE, "plist-multi-file", "Output analysis results using Plists (allowing for mult-file bugs)", createPlistMultiFileDiagnosticConsumer)
+ANALYSIS_DIAGNOSTICS(PLIST_HTML, "plist-html", "Output analysis results using HTML wrapped with Plists", createPlistHTMLDiagnosticConsumer)
+ANALYSIS_DIAGNOSTICS(TEXT, "text", "Text output of analysis results", createTextPathDiagnosticConsumer)
 
 #ifndef ANALYSIS_PURGE
 #define ANALYSIS_PURGE(NAME, CMDFLAG, DESC)

Modified: cfe/trunk/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h?rev=188514&r1=188513&r2=188514&view=diff
==============================================================================
--- cfe/trunk/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h (original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h Thu Aug 15 20:06:30 2013
@@ -52,7 +52,7 @@ NumConstraints
 /// AnalysisDiagClients - Set of available diagnostic clients for rendering
 ///  analysis results.
 enum AnalysisDiagClients {
-#define ANALYSIS_DIAGNOSTICS(NAME, CMDFLAG, DESC, CREATFN, AUTOCREAT) PD_##NAME,
+#define ANALYSIS_DIAGNOSTICS(NAME, CMDFLAG, DESC, CREATFN) PD_##NAME,
 #include "clang/StaticAnalyzer/Core/Analyses.def"
 NUM_ANALYSIS_DIAG_CLIENTS
 };

Modified: cfe/trunk/include/clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h?rev=188514&r1=188513&r2=188514&view=diff
==============================================================================
--- cfe/trunk/include/clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h (original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h Thu Aug 15 20:06:30 2013
@@ -97,7 +97,6 @@ public:
   enum PathGenerationScheme { None, Minimal, Extensive, AlternateExtensive };
   virtual PathGenerationScheme getGenerationScheme() const { return Minimal; }
   virtual bool supportsLogicalOpControlFlow() const { return false; }
-  virtual bool supportsAllBlockEdges() const { return false; }
   
   /// Return true if the PathDiagnosticConsumer supports individual
   /// PathDiagnostics that span multiple files.

Modified: cfe/trunk/include/clang/StaticAnalyzer/Core/PathDiagnosticConsumers.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Core/PathDiagnosticConsumers.h?rev=188514&r1=188513&r2=188514&view=diff
==============================================================================
--- cfe/trunk/include/clang/StaticAnalyzer/Core/PathDiagnosticConsumers.h (original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Core/PathDiagnosticConsumers.h Thu Aug 15 20:06:30 2013
@@ -27,18 +27,12 @@ namespace ento {
 class PathDiagnosticConsumer;
 typedef std::vector<PathDiagnosticConsumer*> PathDiagnosticConsumers;
 
-#define CREATE_CONSUMER(NAME)\
-void create ## NAME ## DiagnosticConsumer(AnalyzerOptions &AnalyzerOpts,\
-                                          PathDiagnosticConsumers &C,\
-                                          const std::string& prefix,\
-                                          const Preprocessor &PP);
-
-CREATE_CONSUMER(HTML)
-CREATE_CONSUMER(Plist)
-CREATE_CONSUMER(PlistMultiFile)
-CREATE_CONSUMER(TextPath)
-
-#undef CREATE_CONSUMER
+#define ANALYSIS_DIAGNOSTICS(NAME, CMDFLAG, DESC, CREATEFN)\
+void CREATEFN(AnalyzerOptions &AnalyzerOpts,\
+              PathDiagnosticConsumers &C,\
+              const std::string &Prefix,\
+              const Preprocessor &PP);
+#include "clang/StaticAnalyzer/Core/Analyses.def"
 
 } // end 'ento' namespace
 } // end 'clang' namespace

Modified: cfe/trunk/lib/Frontend/CompilerInvocation.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/CompilerInvocation.cpp?rev=188514&r1=188513&r2=188514&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/CompilerInvocation.cpp (original)
+++ cfe/trunk/lib/Frontend/CompilerInvocation.cpp Thu Aug 15 20:06:30 2013
@@ -167,7 +167,7 @@ static bool ParseAnalyzerArgs(AnalyzerOp
   if (Arg *A = Args.getLastArg(OPT_analyzer_output)) {
     StringRef Name = A->getValue();
     AnalysisDiagClients Value = llvm::StringSwitch<AnalysisDiagClients>(Name)
-#define ANALYSIS_DIAGNOSTICS(NAME, CMDFLAG, DESC, CREATFN, AUTOCREAT) \
+#define ANALYSIS_DIAGNOSTICS(NAME, CMDFLAG, DESC, CREATFN) \
       .Case(CMDFLAG, PD_##NAME)
 #include "clang/StaticAnalyzer/Core/Analyses.def"
       .Default(NUM_ANALYSIS_DIAG_CLIENTS);

Modified: cfe/trunk/lib/StaticAnalyzer/Core/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/CMakeLists.txt?rev=188514&r1=188513&r2=188514&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/CMakeLists.txt (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/CMakeLists.txt Thu Aug 15 20:06:30 2013
@@ -38,7 +38,6 @@ add_clang_library(clangStaticAnalyzerCor
   Store.cpp
   SubEngine.cpp
   SymbolManager.cpp
-  TextPathDiagnostics.cpp
   )
 
 add_dependencies(clangStaticAnalyzerCore

Modified: cfe/trunk/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp?rev=188514&r1=188513&r2=188514&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp Thu Aug 15 20:06:30 2013
@@ -50,7 +50,6 @@ namespace {
 
     PathGenerationScheme getGenerationScheme() const { return Extensive; }
     bool supportsLogicalOpControlFlow() const { return true; }
-    bool supportsAllBlockEdges() const { return true; }
     virtual bool supportsCrossFileDiagnostics() const {
       return SupportsCrossFileDiagnostics;
     }

Removed: cfe/trunk/lib/StaticAnalyzer/Core/TextPathDiagnostics.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/TextPathDiagnostics.cpp?rev=188513&view=auto
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/TextPathDiagnostics.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/TextPathDiagnostics.cpp (removed)
@@ -1,72 +0,0 @@
-//===--- TextPathDiagnostics.cpp - Text Diagnostics for Paths ---*- C++ -*-===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-//  This file defines the TextPathDiagnostics object.
-//
-//===----------------------------------------------------------------------===//
-
-#include "clang/StaticAnalyzer/Core/PathDiagnosticConsumers.h"
-#include "clang/Lex/Preprocessor.h"
-#include "clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h"
-#include "llvm/Support/raw_ostream.h"
-using namespace clang;
-using namespace ento;
-using namespace llvm;
-
-namespace {
-
-/// \brief Simple path diagnostic client used for outputting as diagnostic notes
-/// the sequence of events.
-class TextPathDiagnostics : public PathDiagnosticConsumer {
-  const std::string OutputFile;
-  DiagnosticsEngine &Diag;
-
-public:
-  TextPathDiagnostics(const std::string& output, DiagnosticsEngine &diag)
-    : OutputFile(output), Diag(diag) {}
-
-  void FlushDiagnosticsImpl(std::vector<const PathDiagnostic *> &Diags,
-                            FilesMade *filesMade);
-  
-  virtual StringRef getName() const {
-    return "TextPathDiagnostics";
-  }
-
-  PathGenerationScheme getGenerationScheme() const { return Minimal; }
-  bool supportsLogicalOpControlFlow() const { return true; }
-  bool supportsAllBlockEdges() const { return true; }
-  virtual bool supportsCrossFileDiagnostics() const { return true; }
-};
-
-} // end anonymous namespace
-
-void ento::createTextPathDiagnosticConsumer(AnalyzerOptions &AnalyzerOpts,
-                                            PathDiagnosticConsumers &C,
-                                            const std::string& out,
-                                            const Preprocessor &PP) {
-  C.push_back(new TextPathDiagnostics(out, PP.getDiagnostics()));
-}
-
-void TextPathDiagnostics::FlushDiagnosticsImpl(
-                              std::vector<const PathDiagnostic *> &Diags,
-                              FilesMade *) {
-  for (std::vector<const PathDiagnostic *>::iterator it = Diags.begin(),
-       et = Diags.end(); it != et; ++it) {
-    const PathDiagnostic *D = *it;
-
-    PathPieces FlatPath = D->path.flatten(/*ShouldFlattenMacros=*/true);
-    for (PathPieces::const_iterator I = FlatPath.begin(), E = FlatPath.end(); 
-         I != E; ++I) {
-      unsigned diagID =
-        Diag.getDiagnosticIDs()->getCustomDiagID(DiagnosticIDs::Note,
-                                                 (*I)->getString());
-      Diag.Report((*I)->getLocation().asLocation(), diagID);
-    }
-  }
-}

Modified: cfe/trunk/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp?rev=188514&r1=188513&r2=188514&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp Thu Aug 15 20:06:30 2013
@@ -66,23 +66,52 @@ STATISTIC(MaxCFGSize, "The maximum numbe
 // Special PathDiagnosticConsumers.
 //===----------------------------------------------------------------------===//
 
-static void createPlistHTMLDiagnosticConsumer(AnalyzerOptions &AnalyzerOpts,
-                                              PathDiagnosticConsumers &C,
-                                              const std::string &prefix,
-                                              const Preprocessor &PP) {
+void ento::createPlistHTMLDiagnosticConsumer(AnalyzerOptions &AnalyzerOpts,
+                                             PathDiagnosticConsumers &C,
+                                             const std::string &prefix,
+                                             const Preprocessor &PP) {
   createHTMLDiagnosticConsumer(AnalyzerOpts, C,
                                llvm::sys::path::parent_path(prefix), PP);
   createPlistDiagnosticConsumer(AnalyzerOpts, C, prefix, PP);
 }
 
+void ento::createTextPathDiagnosticConsumer(AnalyzerOptions &AnalyzerOpts,
+                                            PathDiagnosticConsumers &C,
+                                            const std::string &Prefix,
+                                            const clang::Preprocessor &PP) {
+  llvm_unreachable("'text' consumer should be enabled on ClangDiags");
+}
+
 namespace {
 class ClangDiagPathDiagConsumer : public PathDiagnosticConsumer {
   DiagnosticsEngine &Diag;
+  bool IncludePath;
 public:
-  ClangDiagPathDiagConsumer(DiagnosticsEngine &Diag) : Diag(Diag) {}
+  ClangDiagPathDiagConsumer(DiagnosticsEngine &Diag)
+    : Diag(Diag), IncludePath(false) {}
   virtual ~ClangDiagPathDiagConsumer() {}
   virtual StringRef getName() const { return "ClangDiags"; }
-  virtual PathGenerationScheme getGenerationScheme() const { return None; }
+
+  virtual bool supportsLogicalOpControlFlow() const { return true; }
+  virtual bool supportsCrossFileDiagnostics() const { return true; }
+
+  virtual PathGenerationScheme getGenerationScheme() const {
+    return IncludePath ? Minimal : None;
+  }
+
+  void enablePaths() {
+    IncludePath = true;
+  }
+
+  void emitDiag(SourceLocation L, unsigned DiagID,
+                ArrayRef<SourceRange> Ranges) {
+    DiagnosticBuilder DiagBuilder = Diag.Report(L, DiagID);
+
+    for (ArrayRef<SourceRange>::iterator I = Ranges.begin(), E = Ranges.end();
+         I != E; ++I) {
+      DiagBuilder << *I;
+    }
+  }
 
   void FlushDiagnosticsImpl(std::vector<const PathDiagnostic *> &Diags,
                             FilesMade *filesMade) {
@@ -102,14 +131,20 @@ public:
       unsigned ErrorDiag = Diag.getCustomDiagID(DiagnosticsEngine::Warning,
                                                 TmpStr);
       SourceLocation L = PD->getLocation().asLocation();
-      DiagnosticBuilder diagBuilder = Diag.Report(L, ErrorDiag);
+      emitDiag(L, ErrorDiag, PD->path.back()->getRanges());
+
+      if (!IncludePath)
+        continue;
 
-      // Get the ranges from the last point in the path.
-      ArrayRef<SourceRange> Ranges = PD->path.back()->getRanges();
+      PathPieces FlatPath = PD->path.flatten(/*ShouldFlattenMacros=*/true);
+      for (PathPieces::const_iterator PI = FlatPath.begin(),
+                                      PE = FlatPath.end();
+           PI != PE; ++PI) {
+        unsigned NoteID = Diag.getCustomDiagID(DiagnosticsEngine::Note,
+                                               (*PI)->getString());
 
-      for (ArrayRef<SourceRange>::iterator I = Ranges.begin(),
-                                           E = Ranges.end(); I != E; ++I) {
-        diagBuilder << *I;
+        SourceLocation NoteLoc = (*PI)->getLocation().asLocation();
+        emitDiag(NoteLoc, NoteID, (*PI)->getRanges());
       }
     }
   }
@@ -186,20 +221,21 @@ public:
 
   void DigestAnalyzerOptions() {
     // Create the PathDiagnosticConsumer.
-    PathConsumers.push_back(new ClangDiagPathDiagConsumer(PP.getDiagnostics()));
+    ClangDiagPathDiagConsumer *clangDiags =
+      new ClangDiagPathDiagConsumer(PP.getDiagnostics());
+    PathConsumers.push_back(clangDiags);
+
+    if (Opts->AnalysisDiagOpt == PD_TEXT) {
+      clangDiags->enablePaths();
 
-    if (!OutDir.empty()) {
+    } else if (!OutDir.empty()) {
       switch (Opts->AnalysisDiagOpt) {
       default:
-#define ANALYSIS_DIAGNOSTICS(NAME, CMDFLAG, DESC, CREATEFN, AUTOCREATE) \
+#define ANALYSIS_DIAGNOSTICS(NAME, CMDFLAG, DESC, CREATEFN) \
         case PD_##NAME: CREATEFN(*Opts.getPtr(), PathConsumers, OutDir, PP);\
         break;
 #include "clang/StaticAnalyzer/Core/Analyses.def"
       }
-    } else if (Opts->AnalysisDiagOpt == PD_TEXT) {
-      // Create the text client even without a specified output file since
-      // it just uses diagnostic notes.
-      createTextPathDiagnosticConsumer(*Opts.getPtr(), PathConsumers, "", PP);
     }
 
     // Create the analyzer component creators.

Added: cfe/trunk/test/Analysis/diagnostics/text-diagnostics.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/diagnostics/text-diagnostics.c?rev=188514&view=auto
==============================================================================
--- cfe/trunk/test/Analysis/diagnostics/text-diagnostics.c (added)
+++ cfe/trunk/test/Analysis/diagnostics/text-diagnostics.c Thu Aug 15 20:06:30 2013
@@ -0,0 +1,21 @@
+// RUN: %clang --analyze -Xanalyzer -analyzer-output=text -fno-caret-diagnostics %s 2>&1 | FileCheck %s
+
+void testA() {
+  int *p = 0;
+  *p = 1;
+
+  // CHECK-LABEL: text-diagnostics.c:{{.*}}:6: warning: Dereference of null pointer (loaded from variable 'p')
+  // CHECK-NEXT: text-diagnostics.c:[[@LINE-4]]:3: note: 'p' initialized to a null pointer value
+  // CHECK-NEXT: text-diagnostics.c:[[@LINE-4]]:6: note: Dereference of null pointer (loaded from variable 'p')
+}
+
+void testB(int *q) {
+  if (q)
+    return;
+  *q = 1;
+
+  // CHECK-LABEL: text-diagnostics.c:{{.*}}:6: warning: Dereference of null pointer (loaded from variable 'q')
+  // CHECK-NEXT: text-diagnostics.c:[[@LINE-5]]:7: note: Assuming 'q' is null
+  // CHECK-NEXT: text-diagnostics.c:[[@LINE-6]]:3: note: Taking false branch
+  // CHECK-NEXT: text-diagnostics.c:[[@LINE-5]]:6: note: Dereference of null pointer (loaded from variable 'q')
+}

Modified: cfe/trunk/test/Analysis/retain-release-path-notes-gc.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/retain-release-path-notes-gc.m?rev=188514&r1=188513&r2=188514&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/retain-release-path-notes-gc.m (original)
+++ cfe/trunk/test/Analysis/retain-release-path-notes-gc.m Thu Aug 15 20:06:30 2013
@@ -40,17 +40,17 @@ CFTypeRef CFGetSomething();
 
 
 void creationViaCFCreate () {
-  CFTypeRef leaked = CFCreateSomething(); // expected-warning{{leak}} expected-note{{Call to function 'CFCreateSomething' returns a Core Foundation object with a +1 retain count.  Core Foundation objects are not automatically garbage collected}}
-  return; // expected-note{{Object leaked: object allocated and stored into 'leaked' is not referenced later in this execution path and has a retain count of +1}}
+  CFTypeRef leaked = CFCreateSomething(); // expected-note{{Call to function 'CFCreateSomething' returns a Core Foundation object with a +1 retain count.  Core Foundation objects are not automatically garbage collected}}
+  return; // expected-warning{{leak}} expected-note{{Object leaked: object allocated and stored into 'leaked' is not referenced later in this execution path and has a retain count of +1}}
 }
 
 void makeCollectable () {
-  CFTypeRef leaked = CFCreateSomething(); // expected-warning{{leak}} expected-note{{Call to function 'CFCreateSomething' returns a Core Foundation object with a +1 retain count.  Core Foundation objects are not automatically garbage collected}}
+  CFTypeRef leaked = CFCreateSomething(); // expected-note{{Call to function 'CFCreateSomething' returns a Core Foundation object with a +1 retain count.  Core Foundation objects are not automatically garbage collected}}
   CFRetain(leaked); // expected-note{{Reference count incremented. The object now has a +2 retain count}}
   CFMakeCollectable(leaked); // expected-note{{In GC mode a call to 'CFMakeCollectable' decrements an object's retain count and registers the object with the garbage collector. An object must have a 0 retain count to be garbage collected. After this call its retain count is +1}}
   NSMakeCollectable(leaked); // expected-note{{In GC mode a call to 'NSMakeCollectable' decrements an object's retain count and registers the object with the garbage collector. Since it now has a 0 retain count the object can be automatically collected by the garbage collector}}
   CFRetain(leaked); // expected-note{{Reference count incremented. The object now has a +1 retain count. The object is not eligible for garbage collection until the retain count reaches 0 again}}
-  return; // expected-note{{Object leaked: object allocated and stored into 'leaked' is not referenced later in this execution path and has a retain count of +1}}
+  return; // expected-warning{{leak}} expected-note{{Object leaked: object allocated and stored into 'leaked' is not referenced later in this execution path and has a retain count of +1}}
 }
 
 void retainReleaseIgnored () {
@@ -63,13 +63,13 @@ void retainReleaseIgnored () {
 
 @implementation Foo (FundamentalRuleUnderGC)
 - (id)getViolation {
-  id object = (id) CFCreateSomething(); // expected-warning{{leak}} expected-note{{Call to function 'CFCreateSomething' returns a Core Foundation object with a +1 retain count.  Core Foundation objects are not automatically garbage collected}}
-  return object; // expected-note{{Object returned to caller as an owning reference (single retain count transferred to caller)}} expected-note{{Object leaked: object allocated and stored into 'object' and returned from method 'getViolation' is potentially leaked when using garbage collection.  Callers of this method do not expect a returned object with a +1 retain count since they expect the object to be managed by the garbage collector}}
+  id object = (id) CFCreateSomething(); // expected-note{{Call to function 'CFCreateSomething' returns a Core Foundation object with a +1 retain count.  Core Foundation objects are not automatically garbage collected}}
+  return object; // expected-warning{{leak}} expected-note{{Object returned to caller as an owning reference (single retain count transferred to caller)}} expected-note{{Object leaked: object allocated and stored into 'object' and returned from method 'getViolation' is potentially leaked when using garbage collection.  Callers of this method do not expect a returned object with a +1 retain count since they expect the object to be managed by the garbage collector}}
 }
 
 - (id)copyViolation {
-  id object = (id) CFCreateSomething(); // expected-warning{{leak}} expected-note{{Call to function 'CFCreateSomething' returns a Core Foundation object with a +1 retain count.  Core Foundation objects are not automatically garbage collected}}
-  return object; // expected-note{{Object returned to caller as an owning reference (single retain count transferred to caller)}} expected-note{{Object leaked: object allocated and stored into 'object' and returned from method 'copyViolation' is potentially leaked when using garbage collection.  Callers of this method do not expect a returned object with a +1 retain count since they expect the object to be managed by the garbage collector}}
+  id object = (id) CFCreateSomething(); // expected-note{{Call to function 'CFCreateSomething' returns a Core Foundation object with a +1 retain count.  Core Foundation objects are not automatically garbage collected}}
+  return object; // expected-warning{{leak}} expected-note{{Object returned to caller as an owning reference (single retain count transferred to caller)}} expected-note{{Object leaked: object allocated and stored into 'object' and returned from method 'copyViolation' is potentially leaked when using garbage collection.  Callers of this method do not expect a returned object with a +1 retain count since they expect the object to be managed by the garbage collector}}
 }
 @end
 

Modified: cfe/trunk/test/Analysis/retain-release-path-notes.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/retain-release-path-notes.m?rev=188514&r1=188513&r2=188514&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/retain-release-path-notes.m (original)
+++ cfe/trunk/test/Analysis/retain-release-path-notes.m Thu Aug 15 20:06:30 2013
@@ -43,33 +43,33 @@ CFTypeRef CFGetSomething();
 
 
 void creationViaAlloc () {
-  id leaked = [[NSObject alloc] init]; // expected-warning{{leak}} expected-note{{Method returns an Objective-C object with a +1 retain count}}
-  return; // expected-note{{Object leaked: object allocated and stored into 'leaked' is not referenced later in this execution path and has a retain count of +1}}
+  id leaked = [[NSObject alloc] init]; // expected-note{{Method returns an Objective-C object with a +1 retain count}}
+  return; // expected-warning{{leak}} expected-note{{Object leaked: object allocated and stored into 'leaked' is not referenced later in this execution path and has a retain count of +1}}
 }
 
 void creationViaCFCreate () {
-  CFTypeRef leaked = CFCreateSomething(); // expected-warning{{leak}} expected-note{{Call to function 'CFCreateSomething' returns a Core Foundation object with a +1 retain count}}
-  return; // expected-note{{Object leaked: object allocated and stored into 'leaked' is not referenced later in this execution path and has a retain count of +1}}
+  CFTypeRef leaked = CFCreateSomething(); // expected-note{{Call to function 'CFCreateSomething' returns a Core Foundation object with a +1 retain count}}
+  return; // expected-warning{{leak}} expected-note{{Object leaked: object allocated and stored into 'leaked' is not referenced later in this execution path and has a retain count of +1}}
 }
 
 void acquisitionViaMethod (Foo *foo) {
-  id leaked = [foo methodWithValue]; // expected-warning{{leak}} expected-note{{Method returns an Objective-C object with a +0 retain count}}
+  id leaked = [foo methodWithValue]; // expected-note{{Method returns an Objective-C object with a +0 retain count}}
   [leaked retain]; // expected-note{{Reference count incremented. The object now has a +1 retain count}}
   [leaked retain]; // expected-note{{Reference count incremented. The object now has a +2 retain count}}
   [leaked release]; // expected-note{{Reference count decremented. The object now has a +1 retain count}}
-  return; // expected-note{{Object leaked: object allocated and stored into 'leaked' is not referenced later in this execution path and has a retain count of +1}}
+  return; // expected-warning{{leak}} expected-note{{Object leaked: object allocated and stored into 'leaked' is not referenced later in this execution path and has a retain count of +1}}
 }
 
 void acquisitionViaProperty (Foo *foo) {
-  id leaked = foo.propertyValue; // expected-warning{{leak}} expected-note{{Property returns an Objective-C object with a +0 retain count}}
+  id leaked = foo.propertyValue; // expected-note{{Property returns an Objective-C object with a +0 retain count}}
   [leaked retain]; // expected-note{{Reference count incremented. The object now has a +1 retain count}}
-  return; // expected-note{{Object leaked: object allocated and stored into 'leaked' is not referenced later in this execution path and has a retain count of +1}}
+  return; // expected-warning{{leak}} expected-note{{Object leaked: object allocated and stored into 'leaked' is not referenced later in this execution path and has a retain count of +1}}
 }
 
 void acquisitionViaCFFunction () {
-  CFTypeRef leaked = CFGetSomething(); // expected-warning{{leak}} expected-note{{Call to function 'CFGetSomething' returns a Core Foundation object with a +0 retain count}}
+  CFTypeRef leaked = CFGetSomething(); // expected-note{{Call to function 'CFGetSomething' returns a Core Foundation object with a +0 retain count}}
   CFRetain(leaked); // expected-note{{Reference count incremented. The object now has a +1 retain count}}
-  return; // expected-note{{Object leaked: object allocated and stored into 'leaked' is not referenced later in this execution path and has a retain count of +1}}
+  return; // expected-warning{{leak}} expected-note{{Object leaked: object allocated and stored into 'leaked' is not referenced later in this execution path and has a retain count of +1}}
 }
 
 void explicitDealloc () {
@@ -98,10 +98,10 @@ void autoreleaseUnowned (Foo *foo) {
 }
 
 void makeCollectableIgnored () {
-  CFTypeRef leaked = CFCreateSomething(); // expected-warning{{leak}} expected-note{{Call to function 'CFCreateSomething' returns a Core Foundation object with a +1 retain count}}
+  CFTypeRef leaked = CFCreateSomething(); // expected-note{{Call to function 'CFCreateSomething' returns a Core Foundation object with a +1 retain count}}
   CFMakeCollectable(leaked); // expected-note{{When GC is not enabled a call to 'CFMakeCollectable' has no effect on its argument}}
   NSMakeCollectable(leaked); // expected-note{{When GC is not enabled a call to 'NSMakeCollectable' has no effect on its argument}}
-  return; // expected-note{{Object leaked: object allocated and stored into 'leaked' is not referenced later in this execution path and has a retain count of +1}}
+  return; // expected-warning{{leak}} expected-note{{Object leaked: object allocated and stored into 'leaked' is not referenced later in this execution path and has a retain count of +1}}
 }
 
 CFTypeRef CFCopyRuleViolation () {
@@ -110,8 +110,8 @@ CFTypeRef CFCopyRuleViolation () {
 }
 
 CFTypeRef CFGetRuleViolation () {
-  CFTypeRef object = CFCreateSomething(); // expected-warning{{leak}} expected-note{{Call to function 'CFCreateSomething' returns a Core Foundation object with a +1 retain count}}
-  return object; // expected-note{{Object returned to caller as an owning reference (single retain count transferred to caller)}} expected-note{{Object leaked: object allocated and stored into 'object' is returned from a function whose name ('CFGetRuleViolation') does not contain 'Copy' or 'Create'.  This violates the naming convention rules given in the Memory Management Guide for Core Foundation}}
+  CFTypeRef object = CFCreateSomething(); // expected-note{{Call to function 'CFCreateSomething' returns a Core Foundation object with a +1 retain count}}
+  return object; // expected-warning{{leak}} expected-note{{Object returned to caller as an owning reference (single retain count transferred to caller)}} expected-note{{Object leaked: object allocated and stored into 'object' is returned from a function whose name ('CFGetRuleViolation') does not contain 'Copy' or 'Create'.  This violates the naming convention rules given in the Memory Management Guide for Core Foundation}}
 }
 
 @implementation Foo (FundamentalMemoryManagementRules)
@@ -131,8 +131,8 @@ CFTypeRef CFGetRuleViolation () {
 }
 
 - (id)getViolation {
-  id result = [[Foo alloc] init]; // expected-warning{{leak}} expected-note{{Method returns an Objective-C object with a +1 retain count}}
-  return result; // expected-note{{Object returned to caller as an owning reference (single retain count transferred to caller)}} expected-note{{Object leaked: object allocated and stored into 'result' is returned from a method whose name ('getViolation') does not start with 'copy', 'mutableCopy', 'alloc' or 'new'.  This violates the naming convention rules given in the Memory Management Guide for Cocoa}}
+  id result = [[Foo alloc] init]; // expected-note{{Method returns an Objective-C object with a +1 retain count}}
+  return result; // expected-warning{{leak}} expected-note{{Object returned to caller as an owning reference (single retain count transferred to caller)}} expected-note{{Object leaked: object allocated and stored into 'result' is returned from a method whose name ('getViolation') does not start with 'copy', 'mutableCopy', 'alloc' or 'new'.  This violates the naming convention rules given in the Memory Management Guide for Cocoa}}
 }
 
 - (id)copyAutorelease {
@@ -228,12 +228,12 @@ static int Cond;
                                 // expected-note at -3 {{Returning from 'initX'}}
                                 // expected-note at -4 {{Object leaked: allocated object 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-warning {{Potential leak of an object}}
+  id y = [[MyObj alloc] initY];
                                 // expected-note at -1 {{Calling 'initY'}}
                                 // expected-note at -2 {{Returning from 'initY'}}
 
   // initZ is not inlined
-  id z = [[MyObj alloc] initZ];
+  id z = [[MyObj alloc] initZ]; // expected-warning {{Potential leak of an object}}
                                 // expected-note at -1 {{Object leaked: allocated object is not referenced later in this execution path and has a retain count of +1}}
 
   [x release];





More information about the cfe-commits mailing list