https://github.com/Aniketsingh54 created https://github.com/llvm/llvm-project/pull/176082
Clang would previously crash with an assertion failure in `LocalInstantiationScope::findInstantiationOf` when compiling a C++20 coroutine that was missing `promise_type::final_suspend`. The crash occurred during `TreeTransform::TransformCoyieldExpr` because the compiler attempted to rebuild the coroutine body even after the promise object failed to form correctly. This led to a lookup for a declaration that was never instantiated. This patch adds a check for `CoroutinePromise` validity in `TransformCoyieldExpr`. If the promise is null or invalid, we now bail out early, preventing the assertion and allowing the compiler to recover gracefully after emitting the error. Fixes #175720 >From 58fb31621f29f699cf3ca678198096a0ed6f8eaf Mon Sep 17 00:00:00 2001 From: Aniket Singh <[email protected]> Date: Thu, 15 Jan 2026 09:32:15 +0530 Subject: [PATCH] [clang] Fix assertion failure when transforming co_yield in invalid coroutine Clang would previously crash with an assertion failure in `LocalInstantiationScope::findInstantiationOf` when compiling a C++20 coroutine that was missing `promise_type::final_suspend`. The crash occurred during `TreeTransform::TransformCoyieldExpr` because the compiler attempted to rebuild the coroutine body even after the promise object failed to form correctly. This led to a lookup for a declaration that was never instantiated. This patch adds a check for `CoroutinePromise` validity in `TransformCoyieldExpr`. If the promise is null or invalid, we now bail out early, preventing the assertion and allowing the compiler to recover gracefully after emitting the error. Fixes #175720 --- clang/lib/Sema/TreeTransform.h | 9 ++++++ .../SemaCXX/coroutine-final-suspend-crash.cpp | 32 +++++++++++++++++++ 2 files changed, 41 insertions(+) create mode 100644 clang/test/SemaCXX/coroutine-final-suspend-crash.cpp diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h index a53d578fc35ac..b51780d36ad11 100644 --- a/clang/lib/Sema/TreeTransform.h +++ b/clang/lib/Sema/TreeTransform.h @@ -8956,6 +8956,15 @@ TreeTransform<Derived>::TransformDependentCoawaitExpr(DependentCoawaitExpr *E) { template<typename Derived> ExprResult TreeTransform<Derived>::TransformCoyieldExpr(CoyieldExpr *E) { + // FINAL FIX: Strict check. + // 1. If we are in a function scope, but the CoroutinePromise is missing + // (null), + // it means the coroutine setup failed (e.g. valid promise type not found). + // 2. If the promise exists but is invalid, we also fail. + if (clang::sema::FunctionScopeInfo *FSI = getSema().getCurFunction()) { + if (!FSI->CoroutinePromise || FSI->CoroutinePromise->isInvalidDecl()) + return ExprError(); + } ExprResult Result = getDerived().TransformInitializer(E->getOperand(), /*NotCopyInit*/false); if (Result.isInvalid()) diff --git a/clang/test/SemaCXX/coroutine-final-suspend-crash.cpp b/clang/test/SemaCXX/coroutine-final-suspend-crash.cpp new file mode 100644 index 0000000000000..c0cb388005b1a --- /dev/null +++ b/clang/test/SemaCXX/coroutine-final-suspend-crash.cpp @@ -0,0 +1,32 @@ +// RUN: %clang_cc1 -std=c++20 -fsyntax-only -verify %s + +#include "Inputs/std-coroutine.h" + +struct Tag {}; +struct Y { + bool await_ready() const; + void await_suspend(std::coroutine_handle<>) const; + void await_resume() const; +}; + +struct Promise { + Tag get_return_object(); + std::suspend_always initial_suspend(); + // We intentionally omit final_suspend to trigger the error path + void unhandled_exception(); + Y yield_value(int); + void return_void(); +}; + +template <class... Args> struct std::coroutine_traits<Tag, Args...> { + using promise_type = Promise; +}; + +template <class T> struct S { + // The error is diagnosed at the function declaration, not the yield statement. + template <class U> static Tag f() { // expected-error {{no member named 'final_suspend' in 'Promise'}} + co_yield 0; + } +}; + +Tag g() { return S<int>::f<void>(); } \ No newline at end of file _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
