This revision was automatically updated to reflect the committed changes. Closed by commit rG6b8c6f15fdd8: [clang][PR55406] CFG for coroutine (authored by urnathan). Herald added a project: clang. Herald added a subscriber: cfe-commits.
Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D126399/new/ https://reviews.llvm.org/D126399 Files: clang/lib/Analysis/CFG.cpp clang/test/SemaCXX/thread-safety-coro.cpp Index: clang/test/SemaCXX/thread-safety-coro.cpp =================================================================== --- /dev/null +++ clang/test/SemaCXX/thread-safety-coro.cpp @@ -0,0 +1,47 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -Wthread-safety -std=c++17 -fcoroutines-ts %s + +// expected-no-diagnostics + +namespace std { +template <typename _Result, typename...> +struct coroutine_traits { + using promise_type = typename _Result::promise_type; +}; + +template <typename _Promise = void> +struct coroutine_handle; + +template <> +struct coroutine_handle<void> { + static coroutine_handle from_address(void *__a) noexcept; + void resume() const noexcept; + void destroy() const noexcept; +}; + +template <typename _Promise> +struct coroutine_handle : coroutine_handle<> {}; + +struct suspend_always { + bool await_ready() const noexcept; + void await_suspend(coroutine_handle<>) const noexcept; + void await_resume() const noexcept; +}; +} // namespace std + +class Task { +public: + struct promise_type { + public: + std::suspend_always initial_suspend() noexcept; + std::suspend_always final_suspend() noexcept; + + Task get_return_object() noexcept; + void unhandled_exception() noexcept; + void return_value(int value) noexcept; + }; +}; + +Task Foo() noexcept { + // ICE'd + co_return({ int frame = 0; 0; }); +} Index: clang/lib/Analysis/CFG.cpp =================================================================== --- clang/lib/Analysis/CFG.cpp +++ clang/lib/Analysis/CFG.cpp @@ -3137,8 +3137,19 @@ return Visit(O, AddStmtChoice::AlwaysAdd, /*ExternallyDestructed=*/true); return Block; } - // co_return - return VisitChildren(S); + + CoreturnStmt *CRS = cast<CoreturnStmt>(S); + auto *B = Block; + if (CFGBlock *R = Visit(CRS->getPromiseCall())) + B = R; + + if (Expr *RV = CRS->getOperand()) + if (RV->getType()->isVoidType() && !isa<InitListExpr>(RV)) + // A non-initlist void expression. + if (CFGBlock *R = Visit(RV)) + B = R; + + return B; } CFGBlock *CFGBuilder::VisitSEHExceptStmt(SEHExceptStmt *ES) {
Index: clang/test/SemaCXX/thread-safety-coro.cpp =================================================================== --- /dev/null +++ clang/test/SemaCXX/thread-safety-coro.cpp @@ -0,0 +1,47 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -Wthread-safety -std=c++17 -fcoroutines-ts %s + +// expected-no-diagnostics + +namespace std { +template <typename _Result, typename...> +struct coroutine_traits { + using promise_type = typename _Result::promise_type; +}; + +template <typename _Promise = void> +struct coroutine_handle; + +template <> +struct coroutine_handle<void> { + static coroutine_handle from_address(void *__a) noexcept; + void resume() const noexcept; + void destroy() const noexcept; +}; + +template <typename _Promise> +struct coroutine_handle : coroutine_handle<> {}; + +struct suspend_always { + bool await_ready() const noexcept; + void await_suspend(coroutine_handle<>) const noexcept; + void await_resume() const noexcept; +}; +} // namespace std + +class Task { +public: + struct promise_type { + public: + std::suspend_always initial_suspend() noexcept; + std::suspend_always final_suspend() noexcept; + + Task get_return_object() noexcept; + void unhandled_exception() noexcept; + void return_value(int value) noexcept; + }; +}; + +Task Foo() noexcept { + // ICE'd + co_return({ int frame = 0; 0; }); +} Index: clang/lib/Analysis/CFG.cpp =================================================================== --- clang/lib/Analysis/CFG.cpp +++ clang/lib/Analysis/CFG.cpp @@ -3137,8 +3137,19 @@ return Visit(O, AddStmtChoice::AlwaysAdd, /*ExternallyDestructed=*/true); return Block; } - // co_return - return VisitChildren(S); + + CoreturnStmt *CRS = cast<CoreturnStmt>(S); + auto *B = Block; + if (CFGBlock *R = Visit(CRS->getPromiseCall())) + B = R; + + if (Expr *RV = CRS->getOperand()) + if (RV->getType()->isVoidType() && !isa<InitListExpr>(RV)) + // A non-initlist void expression. + if (CFGBlock *R = Visit(RV)) + B = R; + + return B; } CFGBlock *CFGBuilder::VisitSEHExceptStmt(SEHExceptStmt *ES) {
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits