https://github.com/tJener updated https://github.com/llvm/llvm-project/pull/85957
>From 386e7dea15739df65ad9ecb3dd7f7dcd23b6acae Mon Sep 17 00:00:00 2001 From: Eric Li <li.zhe....@gmail.com> Date: Wed, 20 Mar 2024 12:15:45 -0400 Subject: [PATCH 1/2] [clang][dataflow] Fix crash when analyzing a coroutine A coroutine function body (`CoroutineBodyStmt`) may have null children, which causes `isa` to segfault. --- .../lib/Analysis/FlowSensitive/AdornedCFG.cpp | 2 +- .../Analysis/FlowSensitive/TransferTest.cpp | 53 ++++++++++++++++++- 2 files changed, 52 insertions(+), 3 deletions(-) diff --git a/clang/lib/Analysis/FlowSensitive/AdornedCFG.cpp b/clang/lib/Analysis/FlowSensitive/AdornedCFG.cpp index 3813b8c3ee8a23..daa73bed1bd9f5 100644 --- a/clang/lib/Analysis/FlowSensitive/AdornedCFG.cpp +++ b/clang/lib/Analysis/FlowSensitive/AdornedCFG.cpp @@ -103,7 +103,7 @@ buildContainsExprConsumedInDifferentBlock( auto CheckChildExprs = [&Result, &StmtToBlock](const Stmt *S, const CFGBlock *Block) { for (const Stmt *Child : S->children()) { - if (!isa<Expr>(Child)) + if (!isa_and_nonnull<Expr>(Child)) continue; const CFGBlock *ChildBlock = StmtToBlock.lookup(Child); if (ChildBlock != Block) diff --git a/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp b/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp index a243535d387257..2dc01a655264f3 100644 --- a/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp +++ b/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp @@ -37,6 +37,40 @@ using ::testing::Ne; using ::testing::NotNull; using ::testing::UnorderedElementsAre; +// Declares a minimal coroutine library. +constexpr llvm::StringRef CoroutineLibrary = R"cc( +struct promise; +struct task; + +namespace std { +template <class, class...> +struct coroutine_traits {}; +template <> +struct coroutine_traits<task> { + using promise_type = promise; +}; + +template <class Promise = void> +struct coroutine_handle { + static constexpr coroutine_handle from_address(void *addr) { return {}; } +}; +} // namespace std + +struct awaitable { + bool await_ready() const noexcept; + void await_suspend(std::coroutine_handle<promise>) const noexcept; + void await_resume() const noexcept; +}; +struct task {}; +struct promise { + task get_return_object(); + awaitable initial_suspend(); + awaitable final_suspend() noexcept; + void unhandled_exception(); + void return_void(); +}; +)cc"; + void runDataflow( llvm::StringRef Code, std::function< @@ -4607,7 +4641,7 @@ TEST(TransferTest, LoopCanProveInvariantForBoolean) { } TEST(TransferTest, DoesNotCrashOnUnionThisExpr) { - std::string Code = R"( + std::string Code = R"cc( union Union { int A; float B; @@ -4618,7 +4652,7 @@ TEST(TransferTest, DoesNotCrashOnUnionThisExpr) { Union B; A = B; } - )"; + )cc"; // This is a crash regression test when calling the transfer function on a // `CXXThisExpr` that refers to a union. runDataflow( @@ -4628,6 +4662,21 @@ TEST(TransferTest, DoesNotCrashOnUnionThisExpr) { LangStandard::lang_cxx17, /*ApplyBuiltinTransfer=*/true, "operator="); } +TEST(TransferTest, DoesNotCrashOnNullChildren) { + std::string Code = (CoroutineLibrary + R"cc( + task foo() noexcept { + co_return; + } + )cc").str(); + // This is a crash regression test when calling `AdornedCFG::build` on a + // statement (in this case, the `CoroutineBodyStmt`) with null children. + runDataflow( + Code, + [](const llvm::StringMap<DataflowAnalysisState<NoopLattice>> &, + ASTContext &) {}, + LangStandard::lang_cxx20, /*ApplyBuiltinTransfer=*/true, "foo"); +} + TEST(TransferTest, StructuredBindingAssignFromStructIntMembersToRefs) { std::string Code = R"( struct A { >From 71a0ade85a22597d74dbd9507115ee74f6d3a2d4 Mon Sep 17 00:00:00 2001 From: Eric Li <li.zhe....@gmail.com> Date: Wed, 20 Mar 2024 12:32:42 -0400 Subject: [PATCH 2/2] fixup! [clang][dataflow] Fix crash when analyzing a coroutine --- clang/unittests/Analysis/FlowSensitive/TransferTest.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp b/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp index 2dc01a655264f3..b8f8f1ada2fb98 100644 --- a/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp +++ b/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp @@ -4667,7 +4667,8 @@ TEST(TransferTest, DoesNotCrashOnNullChildren) { task foo() noexcept { co_return; } - )cc").str(); + )cc") + .str(); // This is a crash regression test when calling `AdornedCFG::build` on a // statement (in this case, the `CoroutineBodyStmt`) with null children. runDataflow( _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits