summaryrefslogtreecommitdiffstats
path: root/clang/lib/StaticAnalyzer/Core/PathDiagnostic.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/StaticAnalyzer/Core/PathDiagnostic.cpp')
-rw-r--r--clang/lib/StaticAnalyzer/Core/PathDiagnostic.cpp126
1 files changed, 7 insertions, 119 deletions
diff --git a/clang/lib/StaticAnalyzer/Core/PathDiagnostic.cpp b/clang/lib/StaticAnalyzer/Core/PathDiagnostic.cpp
index 94d1c095b8b..853029ac7b0 100644
--- a/clang/lib/StaticAnalyzer/Core/PathDiagnostic.cpp
+++ b/clang/lib/StaticAnalyzer/Core/PathDiagnostic.cpp
@@ -30,7 +30,6 @@
#include "clang/Basic/SourceLocation.h"
#include "clang/Basic/SourceManager.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h"
-#include "clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/FoldingSet.h"
#include "llvm/ADT/None.h"
@@ -524,12 +523,12 @@ PathDiagnosticConsumer::FilesMade::getFiles(const PathDiagnostic &PD) {
// PathDiagnosticLocation methods.
//===----------------------------------------------------------------------===//
-static SourceLocation getValidSourceLocation(const Stmt* S,
- LocationOrAnalysisDeclContext LAC,
- bool UseEnd = false) {
- SourceLocation L = UseEnd ? S->getEndLoc() : S->getBeginLoc();
- assert(!LAC.isNull() && "A valid LocationContext or AnalysisDeclContext should "
- "be passed to PathDiagnosticLocation upon creation.");
+SourceLocation PathDiagnosticLocation::getValidSourceLocation(
+ const Stmt *S, LocationOrAnalysisDeclContext LAC, bool UseEndOfStatement) {
+ SourceLocation L = UseEndOfStatement ? S->getEndLoc() : S->getBeginLoc();
+ assert(!LAC.isNull() &&
+ "A valid LocationContext or AnalysisDeclContext should be passed to "
+ "PathDiagnosticLocation upon creation.");
// S might be a temporary statement that does not have a location in the
// source code, so find an enclosing statement and use its location.
@@ -559,7 +558,7 @@ static SourceLocation getValidSourceLocation(const Stmt* S,
break;
}
- L = UseEnd ? Parent->getEndLoc() : Parent->getBeginLoc();
+ L = UseEndOfStatement ? Parent->getEndLoc() : Parent->getBeginLoc();
} while (!L.isValid());
}
@@ -778,117 +777,6 @@ PathDiagnosticLocation::create(const ProgramPoint& P,
return PathDiagnosticLocation(S, SMng, P.getLocationContext());
}
-static const LocationContext *
-findTopAutosynthesizedParentContext(const LocationContext *LC) {
- assert(LC->getAnalysisDeclContext()->isBodyAutosynthesized());
- const LocationContext *ParentLC = LC->getParent();
- assert(ParentLC && "We don't start analysis from autosynthesized code");
- while (ParentLC->getAnalysisDeclContext()->isBodyAutosynthesized()) {
- LC = ParentLC;
- ParentLC = LC->getParent();
- assert(ParentLC && "We don't start analysis from autosynthesized code");
- }
- return LC;
-}
-
-const Stmt *PathDiagnosticLocation::getStmt(const ExplodedNode *N) {
- // We cannot place diagnostics on autosynthesized code.
- // Put them onto the call site through which we jumped into autosynthesized
- // code for the first time.
- const LocationContext *LC = N->getLocationContext();
- if (LC->getAnalysisDeclContext()->isBodyAutosynthesized()) {
- // It must be a stack frame because we only autosynthesize functions.
- return cast<StackFrameContext>(findTopAutosynthesizedParentContext(LC))
- ->getCallSite();
- }
- // Otherwise, see if the node's program point directly points to a statement.
- ProgramPoint P = N->getLocation();
- if (auto SP = P.getAs<StmtPoint>())
- return SP->getStmt();
- if (auto BE = P.getAs<BlockEdge>())
- return BE->getSrc()->getTerminatorStmt();
- if (auto CE = P.getAs<CallEnter>())
- return CE->getCallExpr();
- if (auto CEE = P.getAs<CallExitEnd>())
- return CEE->getCalleeContext()->getCallSite();
- if (auto PIPP = P.getAs<PostInitializer>())
- return PIPP->getInitializer()->getInit();
- if (auto CEB = P.getAs<CallExitBegin>())
- return CEB->getReturnStmt();
- if (auto FEP = P.getAs<FunctionExitPoint>())
- return FEP->getStmt();
-
- return nullptr;
-}
-
-const Stmt *PathDiagnosticLocation::getNextStmt(const ExplodedNode *N) {
- for (N = N->getFirstSucc(); N; N = N->getFirstSucc()) {
- if (const Stmt *S = getStmt(N)) {
- // Check if the statement is '?' or '&&'/'||'. These are "merges",
- // not actual statement points.
- switch (S->getStmtClass()) {
- case Stmt::ChooseExprClass:
- case Stmt::BinaryConditionalOperatorClass:
- case Stmt::ConditionalOperatorClass:
- continue;
- case Stmt::BinaryOperatorClass: {
- BinaryOperatorKind Op = cast<BinaryOperator>(S)->getOpcode();
- if (Op == BO_LAnd || Op == BO_LOr)
- continue;
- break;
- }
- default:
- break;
- }
- // We found the statement, so return it.
- return S;
- }
- }
-
- return nullptr;
-}
-
-PathDiagnosticLocation
-PathDiagnosticLocation::createEndOfPath(const ExplodedNode *N) {
- assert(N && "Cannot create a location with a null node.");
- const Stmt *S = getStmt(N);
- const LocationContext *LC = N->getLocationContext();
- SourceManager &SM =
- N->getState()->getStateManager().getContext().getSourceManager();
-
- if (!S) {
- // If this is an implicit call, return the implicit call point location.
- if (Optional<PreImplicitCall> PIE = N->getLocationAs<PreImplicitCall>())
- return PathDiagnosticLocation(PIE->getLocation(), SM);
- if (auto FE = N->getLocationAs<FunctionExitPoint>()) {
- if (const ReturnStmt *RS = FE->getStmt())
- return PathDiagnosticLocation::createBegin(RS, SM, LC);
- }
- S = getNextStmt(N);
- }
-
- if (S) {
- ProgramPoint P = N->getLocation();
-
- // For member expressions, return the location of the '.' or '->'.
- if (const auto *ME = dyn_cast<MemberExpr>(S))
- return PathDiagnosticLocation::createMemberLoc(ME, SM);
-
- // For binary operators, return the location of the operator.
- if (const auto *B = dyn_cast<BinaryOperator>(S))
- return PathDiagnosticLocation::createOperatorLoc(B, SM);
-
- if (P.getAs<PostStmtPurgeDeadSymbols>())
- return PathDiagnosticLocation::createEnd(S, SM, LC);
-
- if (S->getBeginLoc().isValid())
- return PathDiagnosticLocation(S, SM, LC);
- return PathDiagnosticLocation(getValidSourceLocation(S, LC), SM);
- }
-
- return createDeclEnd(N->getLocationContext(), SM);
-}
-
PathDiagnosticLocation PathDiagnosticLocation::createSingleLocation(
const PathDiagnosticLocation &PDL) {
FullSourceLoc L = PDL.asLocation();
OpenPOWER on IntegriCloud