diff --git a/clang/lib/ScalableStaticAnalysis/Core/WholeProgramAnalysis/AnalysisDriver.cpp b/clang/lib/ScalableStaticAnalysis/Core/WholeProgramAnalysis/AnalysisDriver.cpp index f60c916e10b67..61e418a2333fa 100644 --- a/clang/lib/ScalableStaticAnalysis/Core/WholeProgramAnalysis/AnalysisDriver.cpp +++ b/clang/lib/ScalableStaticAnalysis/Core/WholeProgramAnalysis/AnalysisDriver.cpp @@ -102,30 +102,16 @@ AnalysisDriver::toposort(llvm::ArrayRef Roots) { llvm::Error AnalysisDriver::executeSummaryAnalysis(SummaryAnalysisBase &Summary, WPASuite &Suite) const { - SummaryName SN = Summary.getSummaryName(); - auto DataIt = LU->Data.find(SN); - if (DataIt == LU->Data.end()) { - return ErrorBuilder::create(std::errc::invalid_argument, - "no data for analysis '{0}' in LUSummary", - Summary.getAnalysisName()) - .build(); - } - - if (auto Err = Summary.initialize()) { + if (auto Err = Summary.initialize()) return Err; - } - for (auto &[Id, EntitySummary] : DataIt->second) { - if (auto Err = Summary.add(Id, *EntitySummary)) { - return Err; - } + auto DataIt = LU->Data.find(Summary.getSummaryName()); + if (DataIt != LU->Data.end()) { + for (auto &[Id, EntitySummary] : DataIt->second) + if (auto Err = Summary.add(Id, *EntitySummary)) + return Err; } - - if (auto Err = Summary.finalize()) { - return Err; - } - - return llvm::Error::success(); + return Summary.finalize(); } llvm::Error AnalysisDriver::executeDerivedAnalysis(DerivedAnalysisBase &Derived, diff --git a/clang/test/Analysis/Scalable/ssaf-analyzer/analyzer.test b/clang/test/Analysis/Scalable/ssaf-analyzer/analyzer.test index 0abdcef15a449..906e051f62178 100644 --- a/clang/test/Analysis/Scalable/ssaf-analyzer/analyzer.test +++ b/clang/test/Analysis/Scalable/ssaf-analyzer/analyzer.test @@ -15,13 +15,13 @@ // UNKNOWN: no analysis registered for 'AnalysisName(NoSuchAnalysis)' // ============================================================================ -// Error: valid analysis name but LUSummary lacks entity data for it +// Success: Analyses might not add summaries in every run. +// Valid analysis name but LUSummary lacks entity data for it is not an error. // ============================================================================ -// RUN: not %clang-ssaf-analyzer-with-plugin %S/Inputs/lu-tags-only.json \ +// RUN: %clang-ssaf-analyzer-with-plugin %S/Inputs/lu-tags-only.json \ // RUN: -o %t/missing-data.json -a PairsAnalysisResult 2>&1 \ -// RUN: | FileCheck %s --check-prefix=MISSING-DATA -// MISSING-DATA: no data for analysis 'AnalysisName(PairsAnalysisResult)' in LUSummary +// RUN: | count 0 // ============================================================================ // Success: run TagsAnalysisResult only (single analysis) diff --git a/clang/unittests/ScalableStaticAnalysis/WholeProgramAnalysis/AnalysisDriverTest.cpp b/clang/unittests/ScalableStaticAnalysis/WholeProgramAnalysis/AnalysisDriverTest.cpp index 95077675fb2ec..9e518f08cc7de 100644 --- a/clang/unittests/ScalableStaticAnalysis/WholeProgramAnalysis/AnalysisDriverTest.cpp +++ b/clang/unittests/ScalableStaticAnalysis/WholeProgramAnalysis/AnalysisDriverTest.cpp @@ -468,15 +468,20 @@ TEST_F(AnalysisDriverTest, RunByName) { "no result for 'AnalysisName(Analysis2)' in WPASuite")); } -// run(names) — error when a requested name has no data in LUSummary. -TEST_F(AnalysisDriverTest, RunByNameErrorMissingData) { +// run(names) — a requested name with no data in the LUSummary yields an empty +// (but initialized and finalized) result rather than an error. +TEST_F(AnalysisDriverTest, RunByNameEmptyWhenMissingData) { auto LU = makeLUSummary(); AnalysisDriver Driver(std::move(LU)); - EXPECT_THAT_EXPECTED( - Driver.run({AnalysisName("Analysis1")}), - llvm::FailedWithMessage( - "no data for analysis 'AnalysisName(Analysis1)' in LUSummary")); + auto WPAOrErr = Driver.run({AnalysisName("Analysis1")}); + ASSERT_THAT_EXPECTED(WPAOrErr, llvm::Succeeded()); + + auto R1OrErr = WPAOrErr->get(); + ASSERT_THAT_EXPECTED(R1OrErr, llvm::Succeeded()); + EXPECT_TRUE(R1OrErr->Entries.empty()); + EXPECT_TRUE(R1OrErr->WasInitialized); + EXPECT_TRUE(R1OrErr->WasFinalized); } // run(names) — error when a requested name has no registered analysis. @@ -522,15 +527,20 @@ TEST_F(AnalysisDriverTest, RunByType) { "no result for 'AnalysisName(Analysis2)' in WPASuite")); } -// run() — error when a requested type has no data in LUSummary. -TEST_F(AnalysisDriverTest, RunByTypeErrorMissingData) { +// run() — a requested type with no data in the LUSummary yields an +// empty (but initialized and finalized) result rather than an error. +TEST_F(AnalysisDriverTest, RunByTypeEmptyWhenMissingData) { auto LU = makeLUSummary(); AnalysisDriver Driver(std::move(LU)); - EXPECT_THAT_EXPECTED( - Driver.run(), - llvm::FailedWithMessage( - "no data for analysis 'AnalysisName(Analysis1)' in LUSummary")); + auto WPAOrErr = Driver.run(); + ASSERT_THAT_EXPECTED(WPAOrErr, llvm::Succeeded()); + + auto R1OrErr = WPAOrErr->get(); + ASSERT_THAT_EXPECTED(R1OrErr, llvm::Succeeded()); + EXPECT_TRUE(R1OrErr->Entries.empty()); + EXPECT_TRUE(R1OrErr->WasInitialized); + EXPECT_TRUE(R1OrErr->WasFinalized); } // contains() — present entries return true; absent entries return false.