From: Ted Kremenek Date: Wed, 29 Feb 2012 23:59:20 +0000 (+0000) Subject: [analyzer] when scanning FIDs in a PathDiagnostic, correctly recurse calls and macros. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=62ff52868976a8494224a2914f1869329777944c;p=clang [analyzer] when scanning FIDs in a PathDiagnostic, correctly recurse calls and macros. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@151774 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/StaticAnalyzer/Core/PathDiagnostic.cpp b/lib/StaticAnalyzer/Core/PathDiagnostic.cpp index 2adc0f2c38..a082bba70d 100644 --- a/lib/StaticAnalyzer/Core/PathDiagnostic.cpp +++ b/lib/StaticAnalyzer/Core/PathDiagnostic.cpp @@ -93,26 +93,43 @@ void PathDiagnosticConsumer::HandlePathDiagnostic(PathDiagnostic *D) { // Verify that the entire path is from the same FileID. FileID FID; const SourceManager &SMgr = (*D->path.begin())->getLocation().getManager(); + llvm::SmallVector WorkList; + WorkList.push_back(&D->path); - for (PathPieces::const_iterator I = D->path.begin(), E = D->path.end(); - I != E; ++I) { - FullSourceLoc L = (*I)->getLocation().asLocation().getExpansionLoc(); - - if (FID.isInvalid()) { - FID = SMgr.getFileID(L); - } else if (SMgr.getFileID(L) != FID) - return; // FIXME: Emit a warning? + while (!WorkList.empty()) { + const PathPieces &path = *WorkList.back(); + WorkList.pop_back(); + + for (PathPieces::const_iterator I = path.begin(), E = path.end(); + I != E; ++I) { + const PathDiagnosticPiece *piece = I->getPtr(); + FullSourceLoc L = piece->getLocation().asLocation().getExpansionLoc(); - // Check the source ranges. - for (PathDiagnosticPiece::range_iterator RI = (*I)->ranges_begin(), - RE = (*I)->ranges_end(); - RI != RE; ++RI) { - SourceLocation L = SMgr.getExpansionLoc(RI->getBegin()); - if (!L.isFileID() || SMgr.getFileID(L) != FID) - return; // FIXME: Emit a warning? - L = SMgr.getExpansionLoc(RI->getEnd()); - if (!L.isFileID() || SMgr.getFileID(L) != FID) + if (FID.isInvalid()) { + FID = SMgr.getFileID(L); + } else if (SMgr.getFileID(L) != FID) return; // FIXME: Emit a warning? + + // Check the source ranges. + for (PathDiagnosticPiece::range_iterator RI = piece->ranges_begin(), + RE = piece->ranges_end(); + RI != RE; ++RI) { + SourceLocation L = SMgr.getExpansionLoc(RI->getBegin()); + if (!L.isFileID() || SMgr.getFileID(L) != FID) + return; // FIXME: Emit a warning? + L = SMgr.getExpansionLoc(RI->getEnd()); + if (!L.isFileID() || SMgr.getFileID(L) != FID) + return; // FIXME: Emit a warning? + } + + if (const PathDiagnosticCallPiece *call = + dyn_cast(piece)) { + WorkList.push_back(&call->path); + } + else if (const PathDiagnosticMacroPiece *macro = + dyn_cast(piece)) { + WorkList.push_back(¯o->subPieces); + } } } diff --git a/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp b/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp index 03e0d89b2d..6f2a5ca931 100644 --- a/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp +++ b/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp @@ -324,19 +324,38 @@ void PlistDiagnostics::FlushDiagnosticsImpl( if (!Diags.empty()) SM = &(*(*Diags.begin())->path.begin())->getLocation().getManager(); + for (std::vector::iterator DI = Diags.begin(), DE = Diags.end(); DI != DE; ++DI) { const PathDiagnostic *D = *DI; - for (PathPieces::const_iterator I = D->path.begin(), E = D->path.end(); - I!=E; ++I) { - AddFID(FM, Fids, SM, (*I)->getLocation().asLocation()); + llvm::SmallVector WorkList; + WorkList.push_back(&D->path); - for (PathDiagnosticPiece::range_iterator RI = (*I)->ranges_begin(), - RE= (*I)->ranges_end(); RI != RE; ++RI) { - AddFID(FM, Fids, SM, RI->getBegin()); - AddFID(FM, Fids, SM, RI->getEnd()); + while (!WorkList.empty()) { + const PathPieces &path = *WorkList.back(); + WorkList.pop_back(); + + for (PathPieces::const_iterator I = path.begin(), E = path.end(); + I!=E; ++I) { + const PathDiagnosticPiece *piece = I->getPtr(); + AddFID(FM, Fids, SM, piece->getLocation().asLocation()); + + for (PathDiagnosticPiece::range_iterator RI = piece->ranges_begin(), + RE= piece->ranges_end(); RI != RE; ++RI) { + AddFID(FM, Fids, SM, RI->getBegin()); + AddFID(FM, Fids, SM, RI->getEnd()); + } + + if (const PathDiagnosticCallPiece *call = + dyn_cast(piece)) { + WorkList.push_back(&call->path); + } + else if (const PathDiagnosticMacroPiece *macro = + dyn_cast(piece)) { + WorkList.push_back(¯o->subPieces); + } } } }