summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArtem Dergachev <artem.dergachev@gmail.com>2019-09-11 20:54:24 +0000
committerArtem Dergachev <artem.dergachev@gmail.com>2019-09-11 20:54:24 +0000
commit7338322a43e9c3c16e547bca691a17ef6081e677 (patch)
tree9bd1e396a5209d265f829beda49e25386d5947b5
parente03d00f8b53eadf0456423cbf66e8d06b9fd41f6 (diff)
downloadclang-7338322a43e9c3c16e547bca691a17ef6081e677.tar.gz
[analyzer] NFC: Move resetDiagnosticLocationToMainFile() to BugReporter.
This method of PathDiagnostic is a part of Static Analyzer's particular path diagnostic construction scheme. As such, it doesn't belong to the PathDiagnostic class, but to the Analyzer. Differential Revision: https://reviews.llvm.org/D67418 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@371660 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h23
-rw-r--r--lib/StaticAnalyzer/Core/BugReporter.cpp67
-rw-r--r--lib/StaticAnalyzer/Core/PathDiagnostic.cpp64
3 files changed, 79 insertions, 75 deletions
diff --git a/include/clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h b/include/clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h
index aaeeb48cf2..fdab18e7fe 100644
--- a/include/clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h
+++ b/include/clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h
@@ -792,11 +792,6 @@ public:
VerboseDesc += S;
}
- /// If the last piece of the report point to the header file, resets
- /// the location of the report to be the last location in the main source
- /// file.
- void resetDiagnosticLocationToMainFile();
-
StringRef getVerboseDescription() const { return VerboseDesc; }
StringRef getShortDescription() const {
@@ -807,11 +802,6 @@ public:
StringRef getBugType() const { return BugType; }
StringRef getCategory() const { return Category; }
- /// Return the semantic context where an issue occurred. If the
- /// issue occurs along a path, this represents the "central" area
- /// where the bug manifests.
- const Decl *getDeclWithIssue() const { return DeclWithIssue; }
-
using meta_iterator = std::deque<std::string>::const_iterator;
meta_iterator meta_begin() const { return OtherDesc.begin(); }
@@ -826,10 +816,23 @@ public:
return *ExecutedLines;
}
+ /// Return the semantic context where an issue occurred. If the
+ /// issue occurs along a path, this represents the "central" area
+ /// where the bug manifests.
+ const Decl *getDeclWithIssue() const { return DeclWithIssue; }
+
+ void setDeclWithIssue(const Decl *D) {
+ DeclWithIssue = D;
+ }
+
PathDiagnosticLocation getLocation() const {
return Loc;
}
+ void setLocation(PathDiagnosticLocation NewLoc) {
+ Loc = NewLoc;
+ }
+
/// Get the location on which the report should be uniqued.
PathDiagnosticLocation getUniqueingLoc() const {
return UniqueingLoc;
diff --git a/lib/StaticAnalyzer/Core/BugReporter.cpp b/lib/StaticAnalyzer/Core/BugReporter.cpp
index 57f639afba..657569dab6 100644
--- a/lib/StaticAnalyzer/Core/BugReporter.cpp
+++ b/lib/StaticAnalyzer/Core/BugReporter.cpp
@@ -3125,6 +3125,71 @@ BugReporter::generateDiagnosticForConsumerMap(
return Out;
}
+static PathDiagnosticCallPiece *
+getFirstStackedCallToHeaderFile(PathDiagnosticCallPiece *CP,
+ const SourceManager &SMgr) {
+ SourceLocation CallLoc = CP->callEnter.asLocation();
+
+ // If the call is within a macro, don't do anything (for now).
+ if (CallLoc.isMacroID())
+ return nullptr;
+
+ assert(AnalysisManager::isInCodeFile(CallLoc, SMgr) &&
+ "The call piece should not be in a header file.");
+
+ // Check if CP represents a path through a function outside of the main file.
+ if (!AnalysisManager::isInCodeFile(CP->callEnterWithin.asLocation(), SMgr))
+ return CP;
+
+ const PathPieces &Path = CP->path;
+ if (Path.empty())
+ return nullptr;
+
+ // Check if the last piece in the callee path is a call to a function outside
+ // of the main file.
+ if (auto *CPInner = dyn_cast<PathDiagnosticCallPiece>(Path.back().get()))
+ return getFirstStackedCallToHeaderFile(CPInner, SMgr);
+
+ // Otherwise, the last piece is in the main file.
+ return nullptr;
+}
+
+static void resetDiagnosticLocationToMainFile(PathDiagnostic &PD) {
+ if (PD.path.empty())
+ return;
+
+ PathDiagnosticPiece *LastP = PD.path.back().get();
+ assert(LastP);
+ const SourceManager &SMgr = LastP->getLocation().getManager();
+
+ // We only need to check if the report ends inside headers, if the last piece
+ // is a call piece.
+ if (auto *CP = dyn_cast<PathDiagnosticCallPiece>(LastP)) {
+ CP = getFirstStackedCallToHeaderFile(CP, SMgr);
+ if (CP) {
+ // Mark the piece.
+ CP->setAsLastInMainSourceFile();
+
+ // Update the path diagnostic message.
+ const auto *ND = dyn_cast<NamedDecl>(CP->getCallee());
+ if (ND) {
+ SmallString<200> buf;
+ llvm::raw_svector_ostream os(buf);
+ os << " (within a call to '" << ND->getDeclName() << "')";
+ PD.appendToDesc(os.str());
+ }
+
+ // Reset the report containing declaration and location.
+ PD.setDeclWithIssue(CP->getCaller());
+ PD.setLocation(CP->getLocation());
+
+ return;
+ }
+ }
+}
+
+
+
std::unique_ptr<DiagnosticForConsumerMapTy>
PathSensitiveBugReporter::generateDiagnosticForConsumerMap(
BugReport *exampleReport, ArrayRef<PathDiagnosticConsumer *> consumers,
@@ -3159,7 +3224,7 @@ PathSensitiveBugReporter::generateDiagnosticForConsumerMap(
const AnalyzerOptions &Opts = getAnalyzerOptions();
for (auto const &P : *Out)
if (Opts.ShouldReportIssuesInMainSourceFile && !Opts.AnalyzeAll)
- P.second->resetDiagnosticLocationToMainFile();
+ resetDiagnosticLocationToMainFile(*P.second);
return Out;
}
diff --git a/lib/StaticAnalyzer/Core/PathDiagnostic.cpp b/lib/StaticAnalyzer/Core/PathDiagnostic.cpp
index 853029ac7b..cc0be8b1b5 100644
--- a/lib/StaticAnalyzer/Core/PathDiagnostic.cpp
+++ b/lib/StaticAnalyzer/Core/PathDiagnostic.cpp
@@ -29,7 +29,6 @@
#include "clang/Basic/LLVM.h"
#include "clang/Basic/SourceLocation.h"
#include "clang/Basic/SourceManager.h"
-#include "clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/FoldingSet.h"
#include "llvm/ADT/None.h"
@@ -130,69 +129,6 @@ PathDiagnostic::PathDiagnostic(
UniqueingDecl(DeclToUnique), ExecutedLines(std::move(ExecutedLines)),
path(pathImpl) {}
-static PathDiagnosticCallPiece *
-getFirstStackedCallToHeaderFile(PathDiagnosticCallPiece *CP,
- const SourceManager &SMgr) {
- SourceLocation CallLoc = CP->callEnter.asLocation();
-
- // If the call is within a macro, don't do anything (for now).
- if (CallLoc.isMacroID())
- return nullptr;
-
- assert(AnalysisManager::isInCodeFile(CallLoc, SMgr) &&
- "The call piece should not be in a header file.");
-
- // Check if CP represents a path through a function outside of the main file.
- if (!AnalysisManager::isInCodeFile(CP->callEnterWithin.asLocation(), SMgr))
- return CP;
-
- const PathPieces &Path = CP->path;
- if (Path.empty())
- return nullptr;
-
- // Check if the last piece in the callee path is a call to a function outside
- // of the main file.
- if (auto *CPInner = dyn_cast<PathDiagnosticCallPiece>(Path.back().get()))
- return getFirstStackedCallToHeaderFile(CPInner, SMgr);
-
- // Otherwise, the last piece is in the main file.
- return nullptr;
-}
-
-void PathDiagnostic::resetDiagnosticLocationToMainFile() {
- if (path.empty())
- return;
-
- PathDiagnosticPiece *LastP = path.back().get();
- assert(LastP);
- const SourceManager &SMgr = LastP->getLocation().getManager();
-
- // We only need to check if the report ends inside headers, if the last piece
- // is a call piece.
- if (auto *CP = dyn_cast<PathDiagnosticCallPiece>(LastP)) {
- CP = getFirstStackedCallToHeaderFile(CP, SMgr);
- if (CP) {
- // Mark the piece.
- CP->setAsLastInMainSourceFile();
-
- // Update the path diagnostic message.
- const auto *ND = dyn_cast<NamedDecl>(CP->getCallee());
- if (ND) {
- SmallString<200> buf;
- llvm::raw_svector_ostream os(buf);
- os << " (within a call to '" << ND->getDeclName() << "')";
- appendToDesc(os.str());
- }
-
- // Reset the report containing declaration and location.
- DeclWithIssue = CP->getCaller();
- Loc = CP->getLocation();
-
- return;
- }
- }
-}
-
void PathDiagnosticConsumer::anchor() {}
PathDiagnosticConsumer::~PathDiagnosticConsumer() {