https://github.com/kinu updated https://github.com/llvm/llvm-project/pull/65732:
>From bc119f4bb478431bf85cda47dbc2a25faa59e85f Mon Sep 17 00:00:00 2001 From: Kinuko Yasuda <kin...@chromium.org> Date: Fri, 8 Sep 2023 09:03:35 +0000 Subject: [PATCH 1/2] [clang][dataflow] Don't crash when BlockToState doesn't have unreached block When we call `getEnvironment`, `BlockToState[BlockId]` for the block can return null even if CFCtx.isBlockReachable(B) returns true if it is called from a particular block that is marked unreachable to the block. (An example is in `EvaluateBlockWithUnreachablePreds` in TransferTest.cpp) --- clang/lib/Analysis/FlowSensitive/Transfer.cpp | 15 +++++++++++++- .../Analysis/FlowSensitive/TransferTest.cpp | 20 +++++++++++++++++++ 2 files changed, 34 insertions(+), 1 deletion(-) diff --git a/clang/lib/Analysis/FlowSensitive/Transfer.cpp b/clang/lib/Analysis/FlowSensitive/Transfer.cpp index 67d8be392ae6053..b46c947c691b9b9 100644 --- a/clang/lib/Analysis/FlowSensitive/Transfer.cpp +++ b/clang/lib/Analysis/FlowSensitive/Transfer.cpp @@ -43,7 +43,20 @@ const Environment *StmtToEnvMap::getEnvironment(const Stmt &S) const { if (!CFCtx.isBlockReachable(*BlockIt->getSecond())) return nullptr; const auto &State = BlockToState[BlockIt->getSecond()->getBlockID()]; - assert(State); + if (!(State)) { + LLVM_DEBUG({ + // State can be null when this block is unreachable from the block that + // called this method. + bool hasUnreachableEdgeFromPred = false; + for (auto B : BlockIt->getSecond()->preds()) + if (!B) { + hasUnreachableEdgeFromPred = true; + break; + } + assert(hasUnreachableEdgeFromPred); + }); + return nullptr; + } return &State->Env; } diff --git a/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp b/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp index 177970ac52a67eb..1fa800044c288d4 100644 --- a/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp +++ b/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp @@ -5853,4 +5853,24 @@ TEST(TransferTest, AnonymousStructWithReferenceField) { }); } +TEST(TransferTest, EvaluateBlockWithUnreachablePreds) { + // This is a crash repro. + // `false` block may not have been processed when we try to evalute the `||` + // after visiting `true`, because it is not necessary (and therefore the edge + // is marked unreachable). Trying to get the analysis state via + // `getEnvironment` for the subexpression should still not crash. + std::string Code = R"( + int cast(int i) { + if ((i < 0 && true) || false) { + return 0; + } + return 0; + } + )"; + runDataflow( + Code, + [](const llvm::StringMap<DataflowAnalysisState<NoopLattice>> &Results, + ASTContext &ASTCtx) {}); +} + } // namespace >From 144cdf860b19f867e8c61c9478713adbe719967b Mon Sep 17 00:00:00 2001 From: Kinuko Yasuda <kin...@chromium.org> Date: Fri, 8 Sep 2023 13:11:49 +0000 Subject: [PATCH 2/2] comment change to see if it triggers build --- clang/unittests/Analysis/FlowSensitive/TransferTest.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp b/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp index 1fa800044c288d4..ec07555d7f33b3b 100644 --- a/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp +++ b/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp @@ -5858,7 +5858,7 @@ TEST(TransferTest, EvaluateBlockWithUnreachablePreds) { // `false` block may not have been processed when we try to evalute the `||` // after visiting `true`, because it is not necessary (and therefore the edge // is marked unreachable). Trying to get the analysis state via - // `getEnvironment` for the subexpression should still not crash. + // `getEnvironment` for the subexpression still should not crash. std::string Code = R"( int cast(int i) { if ((i < 0 && true) || false) { _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits