Index: clang/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h =================================================================== --- clang/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h +++ clang/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h @@ -210,7 +210,7 @@ Notes.push_back(std::move(P)); } - ArrayRef> getNotes() { + ArrayRef> getNotes() const { return Notes; } @@ -657,7 +657,7 @@ protected: /// Generate the diagnostics for the given bug report. virtual std::unique_ptr - generateDiagnosticForConsumerMap(BugReport *exampleReport, + generateDiagnosticForConsumerMap(const BugReport *&exampleReport, ArrayRef consumers, ArrayRef bugReports); }; @@ -672,9 +672,10 @@ /// Generate the diagnostics for the given bug report. std::unique_ptr - generateDiagnosticForConsumerMap(BugReport *exampleReport, + generateDiagnosticForConsumerMap(const BugReport *&exampleReport, ArrayRef consumers, ArrayRef bugReports) override; + public: PathSensitiveBugReporter(BugReporterData& d, ExprEngine& eng) : BugReporter(d), Eng(eng) {} @@ -692,9 +693,10 @@ /// \return A mapping from consumers to the corresponding diagnostics. /// Iterates through the bug reports within a single equivalence class, /// stops at a first non-invalidated report. - std::unique_ptr generatePathDiagnostics( - ArrayRef consumers, - ArrayRef &bugReports); + std::unique_ptr + generatePathDiagnostics(const BugReport *&exampleReport, + ArrayRef consumers, + ArrayRef &bugReports); void emitReport(std::unique_ptr R) override; }; Index: clang/lib/StaticAnalyzer/Core/BugReporter.cpp =================================================================== --- clang/lib/StaticAnalyzer/Core/BugReporter.cpp +++ clang/lib/StaticAnalyzer/Core/BugReporter.cpp @@ -244,6 +244,9 @@ std::unique_ptr generate(const PathDiagnosticConsumer *PDC) const; + /// Get the bug report used to generate the PathDiagnostic. + const PathSensitiveBugReport *getBugReport() const { return R; } + private: void updateStackPiecesWithMessage(PathDiagnosticPieceRef P, const CallWithEntryStack &CallStack) const; @@ -271,8 +274,6 @@ PathDiagnosticLocation ExecutionContinues(llvm::raw_string_ostream &os, const PathDiagnosticConstruct &C) const; - - const PathSensitiveBugReport *getBugReport() const { return R; } }; } // namespace @@ -2874,6 +2875,7 @@ std::unique_ptr PathSensitiveBugReporter::generatePathDiagnostics( + const BugReport *&exampleReport, ArrayRef consumers, ArrayRef &bugReports) { assert(!bugReports.empty()); @@ -2889,6 +2891,7 @@ (*Out)[PC] = std::move(PD); } } + exampleReport = PDB->getBugReport(); } return Out; @@ -3062,7 +3065,7 @@ void BugReporter::FlushReport(BugReportEquivClass& EQ) { SmallVector bugReports; - BugReport *report = findReportInEquivalenceClass(EQ, bugReports); + const BugReport *report = findReportInEquivalenceClass(EQ, bugReports); if (!report) return; @@ -3200,7 +3203,8 @@ std::unique_ptr BugReporter::generateDiagnosticForConsumerMap( - BugReport *exampleReport, ArrayRef consumers, + const BugReport *&exampleReport, + ArrayRef consumers, ArrayRef bugReports) { auto *basicReport = cast(exampleReport); auto Out = std::make_unique(); @@ -3272,11 +3276,10 @@ } } - - std::unique_ptr PathSensitiveBugReporter::generateDiagnosticForConsumerMap( - BugReport *exampleReport, ArrayRef consumers, + const BugReport *&exampleReport, + ArrayRef consumers, ArrayRef bugReports) { std::vector BasicBugReports; std::vector PathSensitiveBugReports; @@ -3296,7 +3299,7 @@ reinterpret_cast(&*bugReports.begin()), reinterpret_cast(&*bugReports.end())); std::unique_ptr Out = generatePathDiagnostics( - consumers, convertedArrayOfReports); + exampleReport, consumers, convertedArrayOfReports); if (Out->empty()) return Out; Index: clang/test/Analysis/keychainAPI.m =================================================================== --- clang/test/Analysis/keychainAPI.m +++ clang/test/Analysis/keychainAPI.m @@ -402,10 +402,10 @@ OSStatus st = 0; void *outData = my_AllocateReturn(&st); if (x) { - consumeChar(*(char*)outData); // expected-warning{{Allocated data is not released:}} + consumeChar(*(char*)outData); return; } else { - consumeChar(*(char*)outData); + consumeChar(*(char*)outData); // expected-warning{{Allocated data is not released:}} } return; } Index: clang/test/Analysis/malloc-plist.c =================================================================== --- clang/test/Analysis/malloc-plist.c +++ clang/test/Analysis/malloc-plist.c @@ -135,8 +135,8 @@ static void function_with_leak3(int y) { char *x = (char*)malloc(12); if (y) - y++; -}//expected-warning{{Potential leak}} + y++;//expected-warning{{Potential leak}} +} void use_function_with_leak3(int y) { function_with_leak3(y); } Index: clang/test/Analysis/stream.c =================================================================== --- clang/test/Analysis/stream.c +++ clang/test/Analysis/stream.c @@ -261,9 +261,7 @@ if (!F1) return; if (Test == 1) { - return; // no warning + return; // expected-warning {{Opened stream never closed. Potential resource leak}} } rewind(F1); -} // expected-warning {{Opened stream never closed. Potential resource leak}} -// FIXME: This warning should be placed at the `return` above. -// See https://reviews.llvm.org/D83120 about details. +} // no warning