balazske created this revision. Herald added subscribers: cfe-commits, ASDenysPetrov, martong, Charusso, gamesh411, dkrupp, donat.nagy, Szelethus, mikhail.ramalho, a.sidorin, szepet, baloghadamsoftware, xazax.hun. Herald added a reviewer: Szelethus. Herald added a project: clang.
Fix of the following problem: If the bug report equivalence class contains multiple reports and no (minimal) analyzer output was requested it can happen that the wrong location is used for the warning. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D83961 Files: clang/lib/Analysis/PathDiagnostic.cpp clang/lib/StaticAnalyzer/Core/BugReporter.cpp Index: clang/lib/StaticAnalyzer/Core/BugReporter.cpp =================================================================== --- clang/lib/StaticAnalyzer/Core/BugReporter.cpp +++ clang/lib/StaticAnalyzer/Core/BugReporter.cpp @@ -1997,9 +1997,6 @@ return nullptr; } - if (!PDC->shouldGenerateDiagnostics()) - return generateEmptyDiagnosticForReport(R, getSourceManager()); - // Construct the final (warning) event for the bug report. auto EndNotes = VisitorsDiagnostics->find(ErrorNode); PathDiagnosticPieceRef LastPiece; @@ -2012,6 +2009,9 @@ } Construct.PD->setEndOfPath(LastPiece); + if (!PDC->shouldGenerateDiagnostics()) + return std::move(Construct.PD); + PathDiagnosticLocation PrevLoc = Construct.PD->getLocation(); // From the error node to the root, ascend the bug path and construct the bug // report. @@ -3004,14 +3004,7 @@ // If the path is empty, generate a single step path with the location // of the issue. - if (PD->path.empty()) { - PathDiagnosticLocation L = report->getLocation(); - auto piece = std::make_unique<PathDiagnosticEventPiece>( - L, report->getDescription()); - for (SourceRange Range : report->getRanges()) - piece->addRange(Range); - PD->setEndOfPath(std::move(piece)); - } + assert(!PD->path.empty() && "Path should contain at least the last piece."); PathPieces &Pieces = PD->getMutablePieces(); if (getAnalyzerOptions().ShouldDisplayNotesAsEvents) { Index: clang/lib/Analysis/PathDiagnostic.cpp =================================================================== --- clang/lib/Analysis/PathDiagnostic.cpp +++ clang/lib/Analysis/PathDiagnostic.cpp @@ -349,6 +349,24 @@ FullSourceLoc YL = Y.getLocation().asLocation(); if (XL != YL) return compareCrossTUSourceLocs(XL, YL); + PathDiagnosticRange XR = X.getLocation().asRange(); + PathDiagnosticRange YR = Y.getLocation().asRange(); + if (XR.isValid() && !YR.isValid()) + return true; + if (!XR.isValid() && YR.isValid()) + return false; + if (XR.isValid() && YR.isValid()) { + if (XR.isPoint && !YR.isPoint) + return true; + if (!XR.isPoint && YR.isPoint) + return false; + if (!XR.isPoint && !YR.isPoint) { + FullSourceLoc XRE{XR.getEnd(), XL.getManager()}; + FullSourceLoc YRE{YR.getEnd(), YL.getManager()}; + if (XRE != YRE) + return compareCrossTUSourceLocs(XRE, YRE); + } + } if (X.getBugType() != Y.getBugType()) return X.getBugType() < Y.getBugType(); if (X.getCategory() != Y.getCategory())
Index: clang/lib/StaticAnalyzer/Core/BugReporter.cpp =================================================================== --- clang/lib/StaticAnalyzer/Core/BugReporter.cpp +++ clang/lib/StaticAnalyzer/Core/BugReporter.cpp @@ -1997,9 +1997,6 @@ return nullptr; } - if (!PDC->shouldGenerateDiagnostics()) - return generateEmptyDiagnosticForReport(R, getSourceManager()); - // Construct the final (warning) event for the bug report. auto EndNotes = VisitorsDiagnostics->find(ErrorNode); PathDiagnosticPieceRef LastPiece; @@ -2012,6 +2009,9 @@ } Construct.PD->setEndOfPath(LastPiece); + if (!PDC->shouldGenerateDiagnostics()) + return std::move(Construct.PD); + PathDiagnosticLocation PrevLoc = Construct.PD->getLocation(); // From the error node to the root, ascend the bug path and construct the bug // report. @@ -3004,14 +3004,7 @@ // If the path is empty, generate a single step path with the location // of the issue. - if (PD->path.empty()) { - PathDiagnosticLocation L = report->getLocation(); - auto piece = std::make_unique<PathDiagnosticEventPiece>( - L, report->getDescription()); - for (SourceRange Range : report->getRanges()) - piece->addRange(Range); - PD->setEndOfPath(std::move(piece)); - } + assert(!PD->path.empty() && "Path should contain at least the last piece."); PathPieces &Pieces = PD->getMutablePieces(); if (getAnalyzerOptions().ShouldDisplayNotesAsEvents) { Index: clang/lib/Analysis/PathDiagnostic.cpp =================================================================== --- clang/lib/Analysis/PathDiagnostic.cpp +++ clang/lib/Analysis/PathDiagnostic.cpp @@ -349,6 +349,24 @@ FullSourceLoc YL = Y.getLocation().asLocation(); if (XL != YL) return compareCrossTUSourceLocs(XL, YL); + PathDiagnosticRange XR = X.getLocation().asRange(); + PathDiagnosticRange YR = Y.getLocation().asRange(); + if (XR.isValid() && !YR.isValid()) + return true; + if (!XR.isValid() && YR.isValid()) + return false; + if (XR.isValid() && YR.isValid()) { + if (XR.isPoint && !YR.isPoint) + return true; + if (!XR.isPoint && YR.isPoint) + return false; + if (!XR.isPoint && !YR.isPoint) { + FullSourceLoc XRE{XR.getEnd(), XL.getManager()}; + FullSourceLoc YRE{YR.getEnd(), YL.getManager()}; + if (XRE != YRE) + return compareCrossTUSourceLocs(XRE, YRE); + } + } if (X.getBugType() != Y.getBugType()) return X.getBugType() < Y.getBugType(); if (X.getCategory() != Y.getCategory())
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits