r283092 - [analyzer] Extend bug reports with extra notes

Artem Dergachev via cfe-commits cfe-commits at lists.llvm.org
Mon Oct 3 20:41:25 PDT 2016


Oh well, will make a few more blind guesses then, with a closer look at 
this bot this time. Thanks for helping/reverting!


04/10/2016 01:12, Vitaly Buka пишет:
> Can't reproduce on my Windows.
>
> On Mon, Oct 3, 2016 at 1:31 PM Artem Dergachev <noqnoqneo at gmail.com 
> <mailto:noqnoqneo at gmail.com>> wrote:
>
>     I also made a quick blind guess at r283141
>     (http://lists.llvm.org/pipermail/cfe-commits/Week-of-Mon-20161003/172390.html)
>
>     Thanks a lot for trying to help, sorry for causing problems.
>
>
>     03/10/2016 23:26, Vitaly Buka пишет:
>>     I will look into this and get back to you.
>>
>>     On Mon, Oct 3, 2016 at 12:12 PM Artem Dergachev
>>     <noqnoqneo at gmail.com <mailto:noqnoqneo at gmail.com>> wrote:
>>
>>         > fatal error C1001: An internal error has occurred in the
>>         compiler.
>>
>>         Ouch. So i managed to *crash* the microsoft compiler with my
>>         code?
>>
>>         Could you please somehow have a look if this is reproducible?
>>         If it's reproducible or hard-to-check-if-reproducible then
>>         i'd revert.
>>
>>         I don't think i can debug this, as i don't have windows, and
>>         i have no guesses from looking at the code.
>>
>>         Also, should i have received an email for this failure? Cause
>>         i haven't received an email for this failure. Hope there
>>         aren't more failures.
>>
>>
>>
>>         03/10/2016 21:46, Vitaly Buka via cfe-commits пишет:
>>>         This patch breaks Windows:
>>>         http://lab.llvm.org:8011/builders/sanitizer-windows/builds/29769/
>>>
>>>         On Mon, Oct 3, 2016 at 1:07 AM Artem Dergachev via
>>>         cfe-commits <cfe-commits at lists.llvm.org
>>>         <mailto:cfe-commits at lists.llvm.org>> wrote:
>>>
>>>             Author: dergachev
>>>             Date: Mon Oct  3 02:58:26 2016
>>>             New Revision: 283092
>>>
>>>             URL: http://llvm.org/viewvc/llvm-project?rev=283092&view=rev
>>>             Log:
>>>             [analyzer] Extend bug reports with extra notes
>>>
>>>             These diagnostics are separate from the path-sensitive
>>>             engine's path notes,
>>>             and can be added manually on top of path-sensitive or
>>>             path-insensitive reports.
>>>
>>>             The new note diagnostics would appear as
>>>             note:-diagnostic on console and
>>>             as blue bubbles in scan-build. In plist files they
>>>             currently do not appear,
>>>             because format needs to be discussed with plist file users.
>>>
>>>             The analyzer option "-analyzer-config
>>>             notes-as-events=true" would convert
>>>             notes to normal path notes, and put them at the
>>>             beginning of the path.
>>>             This is a temporary hack to show the new notes in plist
>>>             files.
>>>
>>>             A few checkers would be updated in subsequent commits,
>>>             including tests for this new feature.
>>>
>>>             Differential Revision: https://reviews.llvm.org/D24278
>>>
>>>             Modified:
>>>             cfe/trunk/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h
>>>             cfe/trunk/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h
>>>             cfe/trunk/include/clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h
>>>                 cfe/trunk/lib/Rewrite/HTMLRewrite.cpp
>>>             cfe/trunk/lib/StaticAnalyzer/Core/AnalyzerOptions.cpp
>>>             cfe/trunk/lib/StaticAnalyzer/Core/BugReporter.cpp
>>>             cfe/trunk/lib/StaticAnalyzer/Core/HTMLDiagnostics.cpp
>>>             cfe/trunk/lib/StaticAnalyzer/Core/PathDiagnostic.cpp
>>>             cfe/trunk/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp
>>>             cfe/trunk/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp
>>>
>>>             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=283092&r1=283091&r2=283092&view=diff
>>>             ==============================================================================
>>>             ---
>>>             cfe/trunk/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h
>>>             (original)
>>>             +++
>>>             cfe/trunk/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h
>>>             Mon Oct  3 02:58:26 2016
>>>             @@ -266,6 +266,9 @@ private:
>>>                /// \sa shouldWidenLoops
>>>                Optional<bool> WidenLoops;
>>>
>>>             +  /// \sa shouldDisplayNotesAsEvents
>>>             +  Optional<bool> DisplayNotesAsEvents;
>>>             +
>>>                /// A helper function that retrieves option for a
>>>             given full-qualified
>>>                /// checker name.
>>>                /// Options for checkers can be specified via
>>>             'analyzer-config' command-line
>>>             @@ -534,6 +537,14 @@ public:
>>>                /// This is controlled by the 'widen-loops' config
>>>             option.
>>>                bool shouldWidenLoops();
>>>
>>>             +  /// Returns true if the bug reporter should
>>>             transparently treat extra note
>>>             +  /// diagnostic pieces as event diagnostic pieces.
>>>             Useful when the diagnostic
>>>             +  /// consumer doesn't support the extra note pieces.
>>>             +  ///
>>>             +  /// This is controlled by the 'notes-as-events'
>>>             option, which defaults
>>>             +  /// to false when unset.
>>>             +  bool shouldDisplayNotesAsEvents();
>>>             +
>>>              public:
>>>                AnalyzerOptions() :
>>>                  AnalysisStoreOpt(RegionStoreModel),
>>>
>>>             Modified:
>>>             cfe/trunk/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h
>>>             URL:
>>>             http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h?rev=283092&r1=283091&r2=283092&view=diff
>>>             ==============================================================================
>>>             ---
>>>             cfe/trunk/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h
>>>             (original)
>>>             +++
>>>             cfe/trunk/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h
>>>             Mon Oct  3 02:58:26 2016
>>>             @@ -66,6 +66,8 @@ public:
>>>                typedef
>>>             SmallVector<std::unique_ptr<BugReporterVisitor>, 8>
>>>             VisitorList;
>>>                typedef VisitorList::iterator visitor_iterator;
>>>                typedef SmallVector<StringRef, 2> ExtraTextList;
>>>             +  typedef
>>>             SmallVector<llvm::IntrusiveRefCntPtr<PathDiagnosticNotePiece>,
>>>             4>
>>>             +      NoteList;
>>>
>>>              protected:
>>>                friend class BugReporter;
>>>             @@ -82,7 +84,8 @@ protected:
>>>                const ExplodedNode *ErrorNode;
>>>                SmallVector<SourceRange, 4> Ranges;
>>>                ExtraTextList ExtraText;
>>>             -
>>>             +  NoteList Notes;
>>>             +
>>>                typedef llvm::DenseSet<SymbolRef> Symbols;
>>>                typedef llvm::DenseSet<const MemRegion *> Regions;
>>>
>>>             @@ -177,6 +180,18 @@ public:
>>>                const BugType& getBugType() const { return BT; }
>>>                BugType& getBugType() { return BT; }
>>>
>>>             +  /// \brief True when the report has an execution path
>>>             associated with it.
>>>             +  ///
>>>             +  /// A report is said to be path-sensitive if it was
>>>             thrown against a
>>>             +  /// particular exploded node in the path-sensitive
>>>             analysis graph.
>>>             +  /// Path-sensitive reports have their intermediate
>>>             path diagnostics
>>>             +  /// auto-generated, perhaps with the help of
>>>             checker-defined visitors,
>>>             +  /// and may contain extra notes.
>>>             +  /// Path-insensitive reports consist only of a single
>>>             warning message
>>>             +  /// in a specific location, and perhaps extra notes.
>>>             +  /// Path-sensitive checkers are allowed to throw
>>>             path-insensitive reports.
>>>             +  bool isPathSensitive() const { return ErrorNode !=
>>>             nullptr; }
>>>             +
>>>                const ExplodedNode *getErrorNode() const { return
>>>             ErrorNode; }
>>>
>>>                StringRef getDescription() const { return Description; }
>>>             @@ -245,7 +260,27 @@ public:
>>>                void setDeclWithIssue(const Decl *declWithIssue) {
>>>                  DeclWithIssue = declWithIssue;
>>>                }
>>>             -
>>>             +
>>>             +  /// Add new item to the list of additional notes that
>>>             need to be attached to
>>>             +  /// this path-insensitive report. If you want to add
>>>             extra notes to a
>>>             +  /// path-sensitive report, you need to use a
>>>             BugReporterVisitor because it
>>>             +  /// allows you to specify where exactly in the
>>>             auto-generated path diagnostic
>>>             +  /// the extra note should appear.
>>>             +  void addNote(StringRef Msg, const
>>>             PathDiagnosticLocation &Pos,
>>>             + ArrayRef<SourceRange> Ranges = {}) {
>>>             +    PathDiagnosticNotePiece *P =
>>>             +        new PathDiagnosticNotePiece(Pos, Msg);
>>>             +
>>>             +    for (const auto &R : Ranges)
>>>             +      P->addRange(R);
>>>             +
>>>             +    Notes.push_back(P);
>>>             +  }
>>>             +
>>>             +  virtual const NoteList &getNotes() {
>>>             +    return Notes;
>>>             +  }
>>>             +
>>>                /// \brief This allows for addition of meta data to
>>>             the diagnostic.
>>>                ///
>>>                /// Currently, only the HTMLDiagnosticClient knows
>>>             how to display it.
>>>
>>>             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=283092&r1=283091&r2=283092&view=diff
>>>             ==============================================================================
>>>             ---
>>>             cfe/trunk/include/clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h
>>>             (original)
>>>             +++
>>>             cfe/trunk/include/clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h
>>>             Mon Oct  3 02:58:26 2016
>>>             @@ -336,7 +336,7 @@ public:
>>>
>>>              class PathDiagnosticPiece : public RefCountedBaseVPTR {
>>>              public:
>>>             -  enum Kind { ControlFlow, Event, Macro, Call };
>>>             +  enum Kind { ControlFlow, Event, Macro, Call, Note };
>>>                enum DisplayHint { Above, Below };
>>>
>>>              private:
>>>             @@ -452,7 +452,8 @@ public:
>>>                void Profile(llvm::FoldingSetNodeID &ID) const override;
>>>
>>>                static bool classof(const PathDiagnosticPiece *P) {
>>>             -    return P->getKind() == Event || P->getKind() == Macro;
>>>             +    return P->getKind() == Event || P->getKind() ==
>>>             Macro ||
>>>             +           P->getKind() == Note;
>>>                }
>>>              };
>>>
>>>             @@ -706,6 +707,23 @@ public:
>>>                }
>>>
>>>                void dump() const override;
>>>             +
>>>             +  void Profile(llvm::FoldingSetNodeID &ID) const override;
>>>             +};
>>>             +
>>>             +class PathDiagnosticNotePiece: public
>>>             PathDiagnosticSpotPiece {
>>>             +public:
>>>             +  PathDiagnosticNotePiece(const PathDiagnosticLocation
>>>             &Pos, StringRef S,
>>>             +                               bool AddPosRange = true)
>>>             +      : PathDiagnosticSpotPiece(Pos, S, Note,
>>>             AddPosRange) {}
>>>             +
>>>             +  ~PathDiagnosticNotePiece() override;
>>>             +
>>>             +  static inline bool classof(const PathDiagnosticPiece
>>>             *P) {
>>>             +    return P->getKind() == Note;
>>>             +  }
>>>             +
>>>             +  void dump() const override;
>>>
>>>                void Profile(llvm::FoldingSetNodeID &ID) const override;
>>>              };
>>>
>>>             Modified: cfe/trunk/lib/Rewrite/HTMLRewrite.cpp
>>>             URL:
>>>             http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Rewrite/HTMLRewrite.cpp?rev=283092&r1=283091&r2=283092&view=diff
>>>             ==============================================================================
>>>             --- cfe/trunk/lib/Rewrite/HTMLRewrite.cpp (original)
>>>             +++ cfe/trunk/lib/Rewrite/HTMLRewrite.cpp Mon Oct  3
>>>             02:58:26 2016
>>>             @@ -324,6 +324,7 @@ void html::AddHeaderFooterInternalBuilti
>>>                    " .msgT { padding:0x; spacing:0x }\n"
>>>                    " .msgEvent { background-color:#fff8b4;
>>>             color:#000000 }\n"
>>>                    " .msgControl { background-color:#bbbbbb;
>>>             color:#000000 }\n"
>>>             +      " .msgNote { background-color:#ddeeff;
>>>             color:#000000 }\n"
>>>                    " .mrange { background-color:#dfddf3 }\n"
>>>                    " .mrange { border-bottom:1px solid #6F9DBE }\n"
>>>                    " .PathIndex { font-weight: bold; padding:0px 5px; "
>>>             @@ -343,8 +344,12 @@ void
>>>             html::AddHeaderFooterInternalBuilti
>>>                    "   border-collapse: collapse; border-spacing:
>>>             0px;\n"
>>>                    " }\n"
>>>                    " td.rowname {\n"
>>>             -      "   text-align:right; font-weight:bold;
>>>             color:#444444;\n"
>>>             -      "   padding-right:2ex; }\n"
>>>             +      "   text-align: right;\n"
>>>             +      "   vertical-align: top;\n"
>>>             +      "   font-weight: bold;\n"
>>>             +      "   color:#444444;\n"
>>>             +      "   padding-right:2ex;\n"
>>>             +      " }\n"
>>>              "</style>\n</head>\n<body>";
>>>
>>>                // Generate header
>>>
>>>             Modified:
>>>             cfe/trunk/lib/StaticAnalyzer/Core/AnalyzerOptions.cpp
>>>             URL:
>>>             http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/AnalyzerOptions.cpp?rev=283092&r1=283091&r2=283092&view=diff
>>>             ==============================================================================
>>>             ---
>>>             cfe/trunk/lib/StaticAnalyzer/Core/AnalyzerOptions.cpp
>>>             (original)
>>>             +++
>>>             cfe/trunk/lib/StaticAnalyzer/Core/AnalyzerOptions.cpp
>>>             Mon Oct  3 02:58:26 2016
>>>             @@ -344,3 +344,10 @@ bool
>>>             AnalyzerOptions::shouldWidenLoops()
>>>                  WidenLoops = getBooleanOption("widen-loops",
>>>             /*Default=*/false);
>>>                return WidenLoops.getValue();
>>>              }
>>>             +
>>>             +bool AnalyzerOptions::shouldDisplayNotesAsEvents() {
>>>             +  if (!DisplayNotesAsEvents.hasValue())
>>>             +    DisplayNotesAsEvents =
>>>             +        getBooleanOption("notes-as-events",
>>>             /*Default=*/false);
>>>             +  return DisplayNotesAsEvents.getValue();
>>>             +}
>>>
>>>             Modified: cfe/trunk/lib/StaticAnalyzer/Core/BugReporter.cpp
>>>             URL:
>>>             http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/BugReporter.cpp?rev=283092&r1=283091&r2=283092&view=diff
>>>             ==============================================================================
>>>             --- cfe/trunk/lib/StaticAnalyzer/Core/BugReporter.cpp
>>>             (original)
>>>             +++ cfe/trunk/lib/StaticAnalyzer/Core/BugReporter.cpp
>>>             Mon Oct  3 02:58:26 2016
>>>             @@ -112,15 +112,15 @@ static void
>>>             removeRedundantMsgs(PathPiec
>>>                  path.pop_front();
>>>
>>>                  switch (piece->getKind()) {
>>>             -      case clang::ento::PathDiagnosticPiece::Call:
>>>             +      case PathDiagnosticPiece::Call:
>>>              removeRedundantMsgs(cast<PathDiagnosticCallPiece>(piece)->path);
>>>                      break;
>>>             -      case clang::ento::PathDiagnosticPiece::Macro:
>>>             +      case PathDiagnosticPiece::Macro:
>>>              removeRedundantMsgs(cast<PathDiagnosticMacroPiece>(piece)->subPieces);
>>>                      break;
>>>             -      case clang::ento::PathDiagnosticPiece::ControlFlow:
>>>             +      case PathDiagnosticPiece::ControlFlow:
>>>                      break;
>>>             -      case clang::ento::PathDiagnosticPiece::Event: {
>>>             +      case PathDiagnosticPiece::Event: {
>>>                      if (i == N-1)
>>>                        break;
>>>
>>>             @@ -140,6 +140,8 @@ static void removeRedundantMsgs(PathPiec
>>>                      }
>>>                      break;
>>>                    }
>>>             +      case PathDiagnosticPiece::Note:
>>>             +        break;
>>>                  }
>>>                  path.push_back(piece);
>>>                }
>>>             @@ -197,6 +199,9 @@ static bool removeUnneededCalls(PathPiec
>>>                    }
>>>                    case PathDiagnosticPiece::ControlFlow:
>>>                      break;
>>>             +
>>>             +      case PathDiagnosticPiece::Note:
>>>             +        break;
>>>                  }
>>>
>>>                  pieces.push_back(piece);
>>>             @@ -3403,25 +3408,28 @@ void
>>>             BugReporter::FlushReport(BugReport
>>>              exampleReport->getUniqueingLocation(),
>>>                    exampleReport->getUniqueingDecl()));
>>>
>>>             -  MaxBugClassSize = std::max(bugReports.size(),
>>>             -  static_cast<size_t>(MaxBugClassSize));
>>>             +  if (exampleReport->isPathSensitive()) {
>>>             +    // Generate the full path diagnostic, using the
>>>             generation scheme
>>>             +    // specified by the PathDiagnosticConsumer. Note
>>>             that we have to generate
>>>             +    // path diagnostics even for consumers which do not
>>>             support paths, because
>>>             +    // the BugReporterVisitors may mark this bug as a
>>>             false positive.
>>>             +    assert(!bugReports.empty());
>>>             +
>>>             +    MaxBugClassSize =
>>>             +        std::max(bugReports.size(),
>>>             static_cast<size_t>(MaxBugClassSize));
>>>
>>>             -  // Generate the full path diagnostic, using the
>>>             generation scheme
>>>             -  // specified by the PathDiagnosticConsumer. Note that
>>>             we have to generate
>>>             -  // path diagnostics even for consumers which do not
>>>             support paths, because
>>>             -  // the BugReporterVisitors may mark this bug as a
>>>             false positive.
>>>             -  if (!bugReports.empty())
>>>                  if (!generatePathDiagnostic(*D.get(), PD, bugReports))
>>>                    return;
>>>
>>>             -  MaxValidBugClassSize = std::max(bugReports.size(),
>>>             - static_cast<size_t>(MaxValidBugClassSize));
>>>             +    MaxValidBugClassSize =
>>>             +        std::max(bugReports.size(),
>>>             static_cast<size_t>(MaxValidBugClassSize));
>>>
>>>             -  // Examine the report and see if the last piece is in
>>>             a header. Reset the
>>>             -  // report location to the last piece in the main
>>>             source file.
>>>             -  AnalyzerOptions& Opts = getAnalyzerOptions();
>>>             -  if (Opts.shouldReportIssuesInMainSourceFile() &&
>>>             !Opts.AnalyzeAll)
>>>             - D->resetDiagnosticLocationToMainFile();
>>>             +    // Examine the report and see if the last piece is
>>>             in a header. Reset the
>>>             +    // report location to the last piece in the main
>>>             source file.
>>>             +    AnalyzerOptions &Opts = getAnalyzerOptions();
>>>             +    if (Opts.shouldReportIssuesInMainSourceFile() &&
>>>             !Opts.AnalyzeAll)
>>>             + D->resetDiagnosticLocationToMainFile();
>>>             +  }
>>>
>>>                // If the path is empty, generate a single step path
>>>             with the location
>>>                // of the issue.
>>>             @@ -3434,6 +3442,27 @@ void
>>>             BugReporter::FlushReport(BugReport
>>>                  D->setEndOfPath(std::move(piece));
>>>                }
>>>
>>>             +  PathPieces &Pieces = D->getMutablePieces();
>>>             +  if (getAnalyzerOptions().shouldDisplayNotesAsEvents()) {
>>>             +    // For path diagnostic consumers that don't support
>>>             extra notes,
>>>             +    // we may optionally convert those to path notes.
>>>             +    for (auto I = exampleReport->getNotes().rbegin(),
>>>             +              E = exampleReport->getNotes().rend(); I
>>>             != E; ++I) {
>>>             +      PathDiagnosticNotePiece *Piece = I->get();
>>>             +      PathDiagnosticEventPiece *ConvertedPiece =
>>>             +          new
>>>             PathDiagnosticEventPiece(Piece->getLocation(),
>>>             +  Piece->getString());
>>>             +      for (const auto &R: Piece->getRanges())
>>>             +        ConvertedPiece->addRange(R);
>>>             +
>>>             +      Pieces.push_front(ConvertedPiece);
>>>             +    }
>>>             +  } else {
>>>             +    for (auto I = exampleReport->getNotes().rbegin(),
>>>             +              E = exampleReport->getNotes().rend(); I
>>>             != E; ++I)
>>>             +      Pieces.push_front(*I);
>>>             +  }
>>>             +
>>>                // Get the meta data.
>>>                const BugReport::ExtraTextList &Meta =
>>>             exampleReport->getExtraText();
>>>                for (BugReport::ExtraTextList::const_iterator i =
>>>             Meta.begin(),
>>>             @@ -3518,6 +3547,13 @@ LLVM_DUMP_METHOD void
>>>             PathDiagnosticMacr
>>>                // FIXME: Print which macro is being invoked.
>>>              }
>>>
>>>             +LLVM_DUMP_METHOD void PathDiagnosticNotePiece::dump()
>>>             const {
>>>             +  llvm::errs() << "NOTE\n--------------\n";
>>>             +  llvm::errs() << getString() << "\n";
>>>             +  llvm::errs() << " ---- at ----\n";
>>>             +  getLocation().dump();
>>>             +}
>>>             +
>>>              LLVM_DUMP_METHOD void PathDiagnosticLocation::dump()
>>>             const {
>>>                if (!isValid()) {
>>>                  llvm::errs() << "<INVALID>\n";
>>>
>>>             Modified:
>>>             cfe/trunk/lib/StaticAnalyzer/Core/HTMLDiagnostics.cpp
>>>             URL:
>>>             http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/HTMLDiagnostics.cpp?rev=283092&r1=283091&r2=283092&view=diff
>>>             ==============================================================================
>>>             ---
>>>             cfe/trunk/lib/StaticAnalyzer/Core/HTMLDiagnostics.cpp
>>>             (original)
>>>             +++
>>>             cfe/trunk/lib/StaticAnalyzer/Core/HTMLDiagnostics.cpp
>>>             Mon Oct  3 02:58:26 2016
>>>             @@ -152,13 +152,30 @@ void
>>>             HTMLDiagnostics::ReportDiag(const P
>>>                }
>>>
>>>                // Process the path.
>>>             -  unsigned n = path.size();
>>>             -  unsigned max = n;
>>>             -
>>>             -  for (PathPieces::const_reverse_iterator I =
>>>             path.rbegin(),
>>>             -       E = path.rend();
>>>             -        I != E; ++I, --n)
>>>             -    HandlePiece(R, FID, **I, n, max);
>>>             +  // Maintain the counts of extra note pieces separately.
>>>             +  unsigned TotalPieces = path.size();
>>>             +  unsigned TotalNotePieces =
>>>             +      std::count_if(path.begin(), path.end(),
>>>             +                    [](const
>>>             IntrusiveRefCntPtr<PathDiagnosticPiece> &p) {
>>>             +                      return
>>>             isa<PathDiagnosticNotePiece>(p.get());
>>>             +                    });
>>>             +
>>>             +  unsigned TotalRegularPieces = TotalPieces -
>>>             TotalNotePieces;
>>>             +  unsigned NumRegularPieces = TotalRegularPieces;
>>>             +  unsigned NumNotePieces = TotalNotePieces;
>>>             +
>>>             +  for (auto I = path.rbegin(), E = path.rend(); I != E;
>>>             ++I) {
>>>             +    if (isa<PathDiagnosticNotePiece>(I->get())) {
>>>             +      // This adds diagnostic bubbles, but not navigation.
>>>             +      // Navigation through note pieces would be added
>>>             later,
>>>             +      // as a separate pass through the piece list.
>>>             +      HandlePiece(R, FID, **I, NumNotePieces,
>>>             TotalNotePieces);
>>>             +      --NumNotePieces;
>>>             +    } else {
>>>             +      HandlePiece(R, FID, **I, NumRegularPieces,
>>>             TotalRegularPieces);
>>>             +      --NumRegularPieces;
>>>             +    }
>>>             +  }
>>>
>>>                // Add line numbers, header, footer, etc.
>>>
>>>             @@ -192,24 +209,38 @@ void
>>>             HTMLDiagnostics::ReportDiag(const P
>>>                int ColumnNumber =
>>>             path.back()->getLocation().asLocation().getExpansionColumnNumber();
>>>
>>>                // Add the name of the file as an <h1> tag.
>>>             -
>>>                {
>>>                  std::string s;
>>>                  llvm::raw_string_ostream os(s);
>>>
>>>                  os << "<!-- REPORTHEADER -->\n"
>>>             -      << "<h3>Bug Summary</h3>\n<table
>>>             class=\"simpletable\">\n"
>>>             +       << "<h3>Bug Summary</h3>\n<table
>>>             class=\"simpletable\">\n"
>>>                        "<tr><td class=\"rowname\">File:</td><td>"
>>>             -      << html::EscapeText(DirName)
>>>             -      << html::EscapeText(Entry->getName())
>>>             -      << "</td></tr>\n<tr><td
>>>             class=\"rowname\">Location:</td><td>"
>>>             -         "<a href=\"#EndPath\">line "
>>>             -      << LineNumber
>>>             -      << ", column "
>>>             -      << ColumnNumber
>>>             -      << "</a></td></tr>\n"
>>>             -         "<tr><td class=\"rowname\">Description:</td><td>"
>>>             -      << D.getVerboseDescription() << "</td></tr>\n";
>>>             +       << html::EscapeText(DirName)
>>>             +       << html::EscapeText(Entry->getName())
>>>             +       << "</td></tr>\n<tr><td
>>>             class=\"rowname\">Warning:</td><td>"
>>>             +          "<a href=\"#EndPath\">line "
>>>             +       << LineNumber
>>>             +       << ", column "
>>>             +       << ColumnNumber
>>>             +       << "</a><br />"
>>>             +       << D.getVerboseDescription() << "</td></tr>\n";
>>>             +
>>>             +    // The navigation across the extra notes pieces.
>>>             +    unsigned NumExtraPieces = 0;
>>>             +    for (const auto &Piece : path) {
>>>             +      if (const auto *P =
>>>             dyn_cast<PathDiagnosticNotePiece>(Piece.get())) {
>>>             +        int LineNumber =
>>>             + P->getLocation().asLocation().getExpansionLineNumber();
>>>             +        int ColumnNumber =
>>>             + P->getLocation().asLocation().getExpansionColumnNumber();
>>>             +        os << "<tr><td class=\"rowname\">Note:</td><td>"
>>>             +           << "<a href=\"#Note" << NumExtraPieces <<
>>>             "\">line "
>>>             +           << LineNumber << ", column " << ColumnNumber
>>>             << "</a><br />"
>>>             +           << P->getString() << "</td></tr>";
>>>             +        ++NumExtraPieces;
>>>             +      }
>>>             +    }
>>>
>>>                  // Output any other meta data.
>>>
>>>             @@ -385,13 +416,20 @@ void
>>>             HTMLDiagnostics::HandlePiece(Rewrit
>>>                // Create the html for the message.
>>>
>>>                const char *Kind = nullptr;
>>>             +  bool IsNote = false;
>>>             +  bool SuppressIndex = (max == 1);
>>>                switch (P.getKind()) {
>>>                case PathDiagnosticPiece::Call:
>>>             -      llvm_unreachable("Calls should already be handled");
>>>             +      llvm_unreachable("Calls and extra notes should
>>>             already be handled");
>>>                case PathDiagnosticPiece::Event:  Kind = "Event"; break;
>>>                case PathDiagnosticPiece::ControlFlow: Kind =
>>>             "Control"; break;
>>>                  // Setting Kind to "Control" is intentional.
>>>                case PathDiagnosticPiece::Macro: Kind = "Control"; break;
>>>             +  case PathDiagnosticPiece::Note:
>>>             +    Kind = "Note";
>>>             +    IsNote = true;
>>>             +    SuppressIndex = true;
>>>             +    break;
>>>                }
>>>
>>>                std::string sbuf;
>>>             @@ -399,7 +437,9 @@ void HTMLDiagnostics::HandlePiece(Rewrit
>>>
>>>                os << "\n<tr><td class=\"num\"></td><td
>>>             class=\"line\"><div id=\"";
>>>
>>>             -  if (num == max)
>>>             +  if (IsNote)
>>>             +    os << "Note" << num;
>>>             +  else if (num == max)
>>>                  os << "EndPath";
>>>                else
>>>                  os << "Path" << num;
>>>             @@ -461,7 +501,7 @@ void HTMLDiagnostics::HandlePiece(Rewrit
>>>
>>>                os << "\">";
>>>
>>>             -  if (max > 1) {
>>>             +  if (!SuppressIndex) {
>>>                  os << "<table class=\"msgT\"><tr><td valign=\"top\">";
>>>                  os << "<div class=\"PathIndex";
>>>                  if (Kind) os << " PathIndex" << Kind;
>>>             @@ -501,7 +541,7 @@ void HTMLDiagnostics::HandlePiece(Rewrit
>>>
>>>                  os << "':\n";
>>>
>>>             -    if (max > 1) {
>>>             +    if (!SuppressIndex) {
>>>                    os << "</td>";
>>>                    if (num < max) {
>>>                      os << "<td><div class=\"PathNav\"><a href=\"#";
>>>             @@ -523,7 +563,7 @@ void HTMLDiagnostics::HandlePiece(Rewrit
>>>                else {
>>>                  os << html::EscapeText(P.getString());
>>>
>>>             -    if (max > 1) {
>>>             +    if (!SuppressIndex) {
>>>                    os << "</td>";
>>>                    if (num < max) {
>>>                      os << "<td><div class=\"PathNav\"><a href=\"#";
>>>
>>>             Modified:
>>>             cfe/trunk/lib/StaticAnalyzer/Core/PathDiagnostic.cpp
>>>             URL:
>>>             http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/PathDiagnostic.cpp?rev=283092&r1=283091&r2=283092&view=diff
>>>             ==============================================================================
>>>             --- cfe/trunk/lib/StaticAnalyzer/Core/PathDiagnostic.cpp
>>>             (original)
>>>             +++ cfe/trunk/lib/StaticAnalyzer/Core/PathDiagnostic.cpp
>>>             Mon Oct  3 02:58:26 2016
>>>             @@ -60,6 +60,7 @@ PathDiagnosticEventPiece::~PathDiagnosti
>>>              PathDiagnosticCallPiece::~PathDiagnosticCallPiece() {}
>>>              PathDiagnosticControlFlowPiece::~PathDiagnosticControlFlowPiece()
>>>             {}
>>>              PathDiagnosticMacroPiece::~PathDiagnosticMacroPiece() {}
>>>             +PathDiagnosticNotePiece::~PathDiagnosticNotePiece() {}
>>>
>>>              void PathPieces::flattenTo(PathPieces &Primary,
>>>             PathPieces &Current,
>>>                                         bool ShouldFlattenMacros)
>>>             const {
>>>             @@ -95,6 +96,7 @@ void PathPieces::flattenTo(PathPieces &P
>>>                  }
>>>                  case PathDiagnosticPiece::Event:
>>>                  case PathDiagnosticPiece::ControlFlow:
>>>             +    case PathDiagnosticPiece::Note:
>>>                    Current.push_back(Piece);
>>>                    break;
>>>                  }
>>>             @@ -342,15 +344,16 @@ static Optional<bool>
>>>             comparePiece(const
>>>                }
>>>
>>>                switch (X.getKind()) {
>>>             -    case clang::ento::PathDiagnosticPiece::ControlFlow:
>>>             +    case PathDiagnosticPiece::ControlFlow:
>>>                    return
>>>             compareControlFlow(cast<PathDiagnosticControlFlowPiece>(X),
>>>              cast<PathDiagnosticControlFlowPiece>(Y));
>>>             -    case clang::ento::PathDiagnosticPiece::Event:
>>>             +    case PathDiagnosticPiece::Event:
>>>             +    case PathDiagnosticPiece::Note:
>>>                    return None;
>>>             -    case clang::ento::PathDiagnosticPiece::Macro:
>>>             +    case PathDiagnosticPiece::Macro:
>>>                    return
>>>             compareMacro(cast<PathDiagnosticMacroPiece>(X),
>>>              cast<PathDiagnosticMacroPiece>(Y));
>>>             -    case clang::ento::PathDiagnosticPiece::Call:
>>>             +    case PathDiagnosticPiece::Call:
>>>                    return compareCall(cast<PathDiagnosticCallPiece>(X),
>>>             cast<PathDiagnosticCallPiece>(Y));
>>>                }
>>>             @@ -1098,6 +1101,10 @@ void
>>>             PathDiagnosticMacroPiece::Profile(l
>>>                  ID.Add(**I);
>>>              }
>>>
>>>             +void
>>>             PathDiagnosticNotePiece::Profile(llvm::FoldingSetNodeID
>>>             &ID) const {
>>>             +  PathDiagnosticSpotPiece::Profile(ID);
>>>             +}
>>>             +
>>>              void PathDiagnostic::Profile(llvm::FoldingSetNodeID
>>>             &ID) const {
>>>                ID.Add(getLocation());
>>>                ID.AddString(BugType);
>>>
>>>             Modified:
>>>             cfe/trunk/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp
>>>             URL:
>>>             http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp?rev=283092&r1=283091&r2=283092&view=diff
>>>             ==============================================================================
>>>             ---
>>>             cfe/trunk/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp
>>>             (original)
>>>             +++
>>>             cfe/trunk/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp
>>>             Mon Oct  3 02:58:26 2016
>>>             @@ -281,6 +281,9 @@ static void ReportPiece(raw_ostream &o,
>>>                    ReportMacro(o, cast<PathDiagnosticMacroPiece>(P),
>>>             FM, SM, LangOpts,
>>>                                indent, depth);
>>>                    break;
>>>             +    case PathDiagnosticPiece::Note:
>>>             +      // FIXME: Extend the plist format to support those.
>>>             +      break;
>>>                }
>>>              }
>>>
>>>
>>>             Modified:
>>>             cfe/trunk/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp
>>>             URL:
>>>             http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp?rev=283092&r1=283091&r2=283092&view=diff
>>>             ==============================================================================
>>>             ---
>>>             cfe/trunk/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp
>>>             (original)
>>>             +++
>>>             cfe/trunk/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp
>>>             Mon Oct  3 02:58:26 2016
>>>             @@ -113,16 +113,28 @@ public:
>>>                    Diag.Report(WarnLoc, WarnID) <<
>>>             PD->getShortDescription()
>>>                                                 <<
>>>             PD->path.back()->getRanges();
>>>
>>>             +      // First, add extra notes, even if paths should
>>>             not be included.
>>>             +      for (const auto &Piece : PD->path) {
>>>             +        if (!isa<PathDiagnosticNotePiece>(Piece.get()))
>>>             +          continue;
>>>             +
>>>             +        SourceLocation NoteLoc =
>>>             Piece->getLocation().asLocation();
>>>             +        Diag.Report(NoteLoc, NoteID) << Piece->getString()
>>>             +                                     << Piece->getRanges();
>>>             +      }
>>>             +
>>>                    if (!IncludePath)
>>>                      continue;
>>>
>>>             +      // Then, add the path notes if necessary.
>>>                    PathPieces FlatPath =
>>>             PD->path.flatten(/*ShouldFlattenMacros=*/true);
>>>             -      for (PathPieces::const_iterator PI =
>>>             FlatPath.begin(),
>>>             -                                      PE = FlatPath.end();
>>>             -           PI != PE; ++PI) {
>>>             -        SourceLocation NoteLoc =
>>>             (*PI)->getLocation().asLocation();
>>>             -        Diag.Report(NoteLoc, NoteID) << (*PI)->getString()
>>>             -                                     << (*PI)->getRanges();
>>>             +      for (const auto &Piece : FlatPath) {
>>>             +        if (isa<PathDiagnosticNotePiece>(Piece.get()))
>>>             +          continue;
>>>             +
>>>             +        SourceLocation NoteLoc =
>>>             Piece->getLocation().asLocation();
>>>             +        Diag.Report(NoteLoc, NoteID) << Piece->getString()
>>>             +                                     << Piece->getRanges();
>>>                    }
>>>                  }
>>>                }
>>>
>>>
>>>             _______________________________________________
>>>             cfe-commits mailing list
>>>             cfe-commits at lists.llvm.org
>>>             <mailto:cfe-commits at lists.llvm.org>
>>>             http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
>>>
>>>
>>>
>>>         _______________________________________________
>>>         cfe-commits mailing list
>>>         cfe-commits at lists.llvm.org <mailto:cfe-commits at lists.llvm.org>
>>>         http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
>>
>

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20161004/0fa5708c/attachment-0001.html>


More information about the cfe-commits mailing list