ayartsev created this revision. ayartsev added reviewers: zaks.anna, dcoughlin. ayartsev added a subscriber: cfe-commits.
Hi all, Currently if the path diagnostic consumer (e.g HTMLDiagnostics and PlistDiagnostics) do not support cross file diagnostics then the path diagnostic report is just silently omitted in the case of cross file diagnostics. If the analyzer finds an issue the missing report looks like a Clang bug as an issue is successfully reported to stdout but no report is generated. The patch adds a little verbosity to Clang in the case considered above. [[ https://llvm.org/bugs/show_bug.cgi?id=12421 | PR12421 ]] is devoted to the issue. Please review! Tried to write tests that would cover warnings inside the 'for' loop, but failed. Any ideas? https://reviews.llvm.org/D22494 Files: lib/StaticAnalyzer/Core/PathDiagnostic.cpp test/Analysis/PR12421.c test/Analysis/PR12421.h Index: test/Analysis/PR12421.h =================================================================== --- test/Analysis/PR12421.h +++ test/Analysis/PR12421.h @@ -0,0 +1,4 @@ +static void f() { + int *p = 0; + *p = 1; // expected-warning{{Dereference of null pointer}} +} Index: test/Analysis/PR12421.c =================================================================== --- test/Analysis/PR12421.c +++ test/Analysis/PR12421.c @@ -0,0 +1,11 @@ +// RUN: %clang_cc1 -analyze -analyzer-checker=core -verify %s +// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-output=html -o PR12421.html %s 2>&1 | FileCheck %s + +#include "PR12421.h" + +int main(){ + f(); + return 0; +} + +// CHECK: warning: Path diagnostic report is not generated. HTMLDiagnostics does not support diagnostics that cross file boundaries. Index: lib/StaticAnalyzer/Core/PathDiagnostic.cpp =================================================================== --- lib/StaticAnalyzer/Core/PathDiagnostic.cpp +++ lib/StaticAnalyzer/Core/PathDiagnostic.cpp @@ -211,6 +211,10 @@ const SourceManager &SMgr = D->path.front()->getLocation().getManager(); SmallVector<const PathPieces *, 5> WorkList; WorkList.push_back(&D->path); + SmallString<128> buf; + llvm::raw_svector_ostream warning(buf); + warning << "warning: Path diagnostic report is not generated. " << getName() + << " does not support diagnostics that cross file boundaries.\n"; while (!WorkList.empty()) { const PathPieces &path = *WorkList.pop_back_val(); @@ -222,19 +226,25 @@ if (FID.isInvalid()) { FID = SMgr.getFileID(L); - } else if (SMgr.getFileID(L) != FID) - return; // FIXME: Emit a warning? + } else if (SMgr.getFileID(L) != FID) { + llvm::errs() << warning.str(); + return; + } // Check the source ranges. ArrayRef<SourceRange> Ranges = piece->getRanges(); for (ArrayRef<SourceRange>::iterator I = Ranges.begin(), E = Ranges.end(); I != E; ++I) { SourceLocation L = SMgr.getExpansionLoc(I->getBegin()); - if (!L.isFileID() || SMgr.getFileID(L) != FID) - return; // FIXME: Emit a warning? + if (!L.isFileID() || SMgr.getFileID(L) != FID) { + llvm::errs() << warning.str(); + return; + } L = SMgr.getExpansionLoc(I->getEnd()); - if (!L.isFileID() || SMgr.getFileID(L) != FID) - return; // FIXME: Emit a warning? + if (!L.isFileID() || SMgr.getFileID(L) != FID) { + llvm::errs() << warning.str(); + return; + } } if (const PathDiagnosticCallPiece *call =
Index: test/Analysis/PR12421.h =================================================================== --- test/Analysis/PR12421.h +++ test/Analysis/PR12421.h @@ -0,0 +1,4 @@ +static void f() { + int *p = 0; + *p = 1; // expected-warning{{Dereference of null pointer}} +} Index: test/Analysis/PR12421.c =================================================================== --- test/Analysis/PR12421.c +++ test/Analysis/PR12421.c @@ -0,0 +1,11 @@ +// RUN: %clang_cc1 -analyze -analyzer-checker=core -verify %s +// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-output=html -o PR12421.html %s 2>&1 | FileCheck %s + +#include "PR12421.h" + +int main(){ + f(); + return 0; +} + +// CHECK: warning: Path diagnostic report is not generated. HTMLDiagnostics does not support diagnostics that cross file boundaries. Index: lib/StaticAnalyzer/Core/PathDiagnostic.cpp =================================================================== --- lib/StaticAnalyzer/Core/PathDiagnostic.cpp +++ lib/StaticAnalyzer/Core/PathDiagnostic.cpp @@ -211,6 +211,10 @@ const SourceManager &SMgr = D->path.front()->getLocation().getManager(); SmallVector<const PathPieces *, 5> WorkList; WorkList.push_back(&D->path); + SmallString<128> buf; + llvm::raw_svector_ostream warning(buf); + warning << "warning: Path diagnostic report is not generated. " << getName() + << " does not support diagnostics that cross file boundaries.\n"; while (!WorkList.empty()) { const PathPieces &path = *WorkList.pop_back_val(); @@ -222,19 +226,25 @@ if (FID.isInvalid()) { FID = SMgr.getFileID(L); - } else if (SMgr.getFileID(L) != FID) - return; // FIXME: Emit a warning? + } else if (SMgr.getFileID(L) != FID) { + llvm::errs() << warning.str(); + return; + } // Check the source ranges. ArrayRef<SourceRange> Ranges = piece->getRanges(); for (ArrayRef<SourceRange>::iterator I = Ranges.begin(), E = Ranges.end(); I != E; ++I) { SourceLocation L = SMgr.getExpansionLoc(I->getBegin()); - if (!L.isFileID() || SMgr.getFileID(L) != FID) - return; // FIXME: Emit a warning? + if (!L.isFileID() || SMgr.getFileID(L) != FID) { + llvm::errs() << warning.str(); + return; + } L = SMgr.getExpansionLoc(I->getEnd()); - if (!L.isFileID() || SMgr.getFileID(L) != FID) - return; // FIXME: Emit a warning? + if (!L.isFileID() || SMgr.getFileID(L) != FID) { + llvm::errs() << warning.str(); + return; + } } if (const PathDiagnosticCallPiece *call =
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits