diff options
Diffstat (limited to 'lib/StaticAnalyzer/Core/PathDiagnostic.cpp')
-rw-r--r-- | lib/StaticAnalyzer/Core/PathDiagnostic.cpp | 94 |
1 files changed, 53 insertions, 41 deletions
diff --git a/lib/StaticAnalyzer/Core/PathDiagnostic.cpp b/lib/StaticAnalyzer/Core/PathDiagnostic.cpp index b504db6349ee..fd25bd8e3af3 100644 --- a/lib/StaticAnalyzer/Core/PathDiagnostic.cpp +++ b/lib/StaticAnalyzer/Core/PathDiagnostic.cpp @@ -16,6 +16,7 @@ #include "clang/AST/DeclCXX.h" #include "clang/AST/DeclObjC.h" #include "clang/AST/Expr.h" +#include "clang/AST/ExprCXX.h" #include "clang/AST/ParentMap.h" #include "clang/AST/StmtCXX.h" #include "clang/Basic/SourceManager.h" @@ -66,7 +67,7 @@ PathPieces::~PathPieces() {} void PathPieces::flattenTo(PathPieces &Primary, PathPieces &Current, bool ShouldFlattenMacros) const { for (PathPieces::const_iterator I = begin(), E = end(); I != E; ++I) { - PathDiagnosticPiece *Piece = I->getPtr(); + PathDiagnosticPiece *Piece = I->get(); switch (Piece->getKind()) { case PathDiagnosticPiece::Call: { @@ -106,12 +107,13 @@ void PathPieces::flattenTo(PathPieces &Primary, PathPieces &Current, PathDiagnostic::~PathDiagnostic() {} -PathDiagnostic::PathDiagnostic(const Decl *declWithIssue, +PathDiagnostic::PathDiagnostic(StringRef CheckName, const Decl *declWithIssue, StringRef bugtype, StringRef verboseDesc, StringRef shortDesc, StringRef category, PathDiagnosticLocation LocationToUnique, const Decl *DeclToUnique) - : DeclWithIssue(declWithIssue), + : CheckName(CheckName), + DeclWithIssue(declWithIssue), BugType(StripTrailingDots(bugtype)), VerboseDesc(StripTrailingDots(verboseDesc)), ShortDesc(StripTrailingDots(shortDesc)), @@ -127,7 +129,7 @@ getFirstStackedCallToHeaderFile(PathDiagnosticCallPiece *CP, // If the call is within a macro, don't do anything (for now). if (CallLoc.isMacroID()) - return 0; + return nullptr; assert(SMgr.isInMainFile(CallLoc) && "The call piece should be in the main file."); @@ -138,7 +140,7 @@ getFirstStackedCallToHeaderFile(PathDiagnosticCallPiece *CP, const PathPieces &Path = CP->path; if (Path.empty()) - return 0; + return nullptr; // Check if the last piece in the callee path is a call to a function outside // of the main file. @@ -148,14 +150,14 @@ getFirstStackedCallToHeaderFile(PathDiagnosticCallPiece *CP, } // Otherwise, the last piece is in the main file. - return 0; + return nullptr; } void PathDiagnostic::resetDiagnosticLocationToMainFile() { if (path.empty()) return; - PathDiagnosticPiece *LastP = path.back().getPtr(); + PathDiagnosticPiece *LastP = path.back().get(); assert(LastP); const SourceManager &SMgr = LastP->getLocation().getManager(); @@ -196,8 +198,8 @@ PathDiagnosticConsumer::~PathDiagnosticConsumer() { } void PathDiagnosticConsumer::HandlePathDiagnostic(PathDiagnostic *D) { - OwningPtr<PathDiagnostic> OwningD(D); - + std::unique_ptr<PathDiagnostic> OwningD(D); + if (!D || D->path.empty()) return; @@ -220,7 +222,7 @@ void PathDiagnosticConsumer::HandlePathDiagnostic(PathDiagnostic *D) { for (PathPieces::const_iterator I = path.begin(), E = path.end(); I != E; ++I) { - const PathDiagnosticPiece *piece = I->getPtr(); + const PathDiagnosticPiece *piece = I->get(); FullSourceLoc L = piece->getLocation().asLocation().getExpansionLoc(); if (FID.isInvalid()) { @@ -258,7 +260,7 @@ void PathDiagnosticConsumer::HandlePathDiagnostic(PathDiagnostic *D) { // Profile the node to see if we already have something matching it llvm::FoldingSetNodeID profile; D->Profile(profile); - void *InsertPos = 0; + void *InsertPos = nullptr; if (PathDiagnostic *orig = Diags.FindNodeOrInsertPos(profile, InsertPos)) { // Keep the PathDiagnostic with the shorter path. @@ -274,8 +276,8 @@ void PathDiagnosticConsumer::HandlePathDiagnostic(PathDiagnostic *D) { Diags.RemoveNode(orig); delete orig; } - - Diags.InsertNode(OwningD.take()); + + Diags.InsertNode(OwningD.release()); } static Optional<bool> comparePath(const PathPieces &X, const PathPieces &Y); @@ -415,17 +417,6 @@ static bool compare(const PathDiagnostic &X, const PathDiagnostic &Y) { return b.getValue(); } -namespace { -struct CompareDiagnostics { - // Compare if 'X' is "<" than 'Y'. - bool operator()(const PathDiagnostic *X, const PathDiagnostic *Y) const { - if (X == Y) - return false; - return compare(*X, *Y); - } -}; -} - void PathDiagnosticConsumer::FlushDiagnostics( PathDiagnosticConsumer::FilesMade *Files) { if (flushed) @@ -443,8 +434,11 @@ void PathDiagnosticConsumer::FlushDiagnostics( // Sort the diagnostics so that they are always emitted in a deterministic // order. if (!BatchDiags.empty()) - std::sort(BatchDiags.begin(), BatchDiags.end(), CompareDiagnostics()); - + std::sort(BatchDiags.begin(), BatchDiags.end(), + [](const PathDiagnostic *X, const PathDiagnostic *Y) { + return X != Y && compare(*X, *Y); + }); + FlushDiagnosticsImpl(BatchDiags, Files); // Delete the flushed diagnostics. @@ -458,6 +452,11 @@ void PathDiagnosticConsumer::FlushDiagnostics( Diags.clear(); } +PathDiagnosticConsumer::FilesMade::~FilesMade() { + for (PDFileEntry &Entry : *this) + Entry.~PDFileEntry(); +} + void PathDiagnosticConsumer::FilesMade::addDiagnostic(const PathDiagnostic &PD, StringRef ConsumerName, StringRef FileName) { @@ -487,7 +486,7 @@ PathDiagnosticConsumer::FilesMade::getFiles(const PathDiagnostic &PD) { void *InsertPos; PDFileEntry *Entry = FindNodeOrInsertPos(NodeID, InsertPos); if (!Entry) - return 0; + return nullptr; return &Entry->files; } @@ -571,6 +570,7 @@ getLocationForCaller(const StackFrameContext *SFC, return PathDiagnosticLocation::create(CallerInfo->getDecl(), SM); } case CFGElement::TemporaryDtor: + case CFGElement::NewAllocator: llvm_unreachable("not yet implemented!"); } @@ -610,6 +610,14 @@ PathDiagnosticLocation } PathDiagnosticLocation + PathDiagnosticLocation::createConditionalColonLoc( + const ConditionalOperator *CO, + const SourceManager &SM) { + return PathDiagnosticLocation(CO->getColonLoc(), SM, SingleLocK); +} + + +PathDiagnosticLocation PathDiagnosticLocation::createMemberLoc(const MemberExpr *ME, const SourceManager &SM) { return PathDiagnosticLocation(ME->getMemberLoc(), SM, SingleLocK); @@ -654,7 +662,7 @@ PathDiagnosticLocation PathDiagnosticLocation::create(const ProgramPoint& P, const SourceManager &SMng) { - const Stmt* S = 0; + const Stmt* S = nullptr; if (Optional<BlockEdge> BE = P.getAs<BlockEdge>()) { const CFGBlock *BSrc = BE->getSrc(); S = BSrc->getTerminatorCondition(); @@ -695,7 +703,7 @@ const Stmt *PathDiagnosticLocation::getStmt(const ExplodedNode *N) { if (Optional<PostInitializer> PIPP = P.getAs<PostInitializer>()) return PIPP->getInitializer()->getInit(); - return 0; + return nullptr; } const Stmt *PathDiagnosticLocation::getNextStmt(const ExplodedNode *N) { @@ -722,7 +730,7 @@ const Stmt *PathDiagnosticLocation::getNextStmt(const ExplodedNode *N) { } } - return 0; + return nullptr; } PathDiagnosticLocation @@ -731,8 +739,12 @@ PathDiagnosticLocation assert(N && "Cannot create a location with a null node."); const Stmt *S = getStmt(N); - if (!S) + 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); S = getNextStmt(N); + } if (S) { ProgramPoint P = N->getLocation(); @@ -853,13 +865,13 @@ PathDiagnosticRange void PathDiagnosticLocation::flatten() { if (K == StmtK) { K = RangeK; - S = 0; - D = 0; + S = nullptr; + D = nullptr; } else if (K == DeclK) { K = SingleLocK; - S = 0; - D = 0; + S = nullptr; + D = nullptr; } } @@ -969,7 +981,7 @@ static bool describeCodeDecl(raw_ostream &Out, const Decl *D, IntrusiveRefCntPtr<PathDiagnosticEventPiece> PathDiagnosticCallPiece::getCallEnterEvent() const { if (!Callee) - return 0; + return nullptr; SmallString<256> buf; llvm::raw_svector_ostream Out(buf); @@ -984,12 +996,12 @@ PathDiagnosticCallPiece::getCallEnterEvent() const { IntrusiveRefCntPtr<PathDiagnosticEventPiece> PathDiagnosticCallPiece::getCallEnterWithinCallerEvent() const { if (!callEnterWithin.asLocation().isValid()) - return 0; + return nullptr; if (Callee->isImplicit() || !Callee->hasBody()) - return 0; + return nullptr; if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(Callee)) if (MD->isDefaulted()) - return 0; + return nullptr; SmallString<256> buf; llvm::raw_svector_ostream Out(buf); @@ -1003,7 +1015,7 @@ PathDiagnosticCallPiece::getCallEnterWithinCallerEvent() const { IntrusiveRefCntPtr<PathDiagnosticEventPiece> PathDiagnosticCallPiece::getCallExitEvent() const { if (NoExit) - return 0; + return nullptr; SmallString<256> buf; llvm::raw_svector_ostream Out(buf); @@ -1025,7 +1037,7 @@ PathDiagnosticCallPiece::getCallExitEvent() const { static void compute_path_size(const PathPieces &pieces, unsigned &size) { for (PathPieces::const_iterator it = pieces.begin(), et = pieces.end(); it != et; ++it) { - const PathDiagnosticPiece *piece = it->getPtr(); + const PathDiagnosticPiece *piece = it->get(); if (const PathDiagnosticCallPiece *cp = dyn_cast<PathDiagnosticCallPiece>(piece)) { compute_path_size(cp->path, size); |