https://github.com/xakep8 updated https://github.com/llvm/llvm-project/pull/237969
>From a361843f242adaec7b0d3dcf8502a1244d8a7e9d Mon Sep 17 00:00:00 2001 From: Kunal Dubey <[email protected]> Date: Mon, 2 Nov 2026 18:59:39 +0530 Subject: [PATCH 1/4] [Clang] Fix crashes in coroutine pack expansions Clang could crash when co_yield or co_await used a parameter pack inside a fold expression like ((void)(co_yield Values),...); Fixed the expression handling so these packs expand correctly. Also added tests for co_yield, co_await and other cases along with negative tests. --- clang/lib/AST/ComputeDependence.cpp | 4 +- .../test/SemaCXX/coroutine-pack-expansion.cpp | 48 +++++++++++++++++++ .../opaque-value-pack-expansion.cpp | 15 ++++++ 3 files changed, 66 insertions(+), 1 deletion(-) create mode 100644 clang/test/SemaCXX/coroutine-pack-expansion.cpp create mode 100644 clang/test/SemaTemplate/opaque-value-pack-expansion.cpp diff --git a/clang/lib/AST/ComputeDependence.cpp b/clang/lib/AST/ComputeDependence.cpp index c4bf3681a79122..6a65b417a4c758 100644 --- a/clang/lib/AST/ComputeDependence.cpp +++ b/clang/lib/AST/ComputeDependence.cpp @@ -27,8 +27,10 @@ ExprDependence clang::computeDependence(FullExpr *E) { ExprDependence clang::computeDependence(OpaqueValueExpr *E) { auto D = toExprDependenceForImpliedType(E->getType()->getDependence()); + // An OpaqueValueExpr has no syntactic children, so it does not contain an + // unexpanded pack even if its source does. if (auto *S = E->getSourceExpr()) - D |= S->getDependence(); + D |= S->getDependence() & ~ExprDependence::UnexpandedPack; assert(!(D & ExprDependence::UnexpandedPack)); return D; } diff --git a/clang/test/SemaCXX/coroutine-pack-expansion.cpp b/clang/test/SemaCXX/coroutine-pack-expansion.cpp new file mode 100644 index 00000000000000..a2478c8975211a --- /dev/null +++ b/clang/test/SemaCXX/coroutine-pack-expansion.cpp @@ -0,0 +1,48 @@ +// RUN: %clang_cc1 -std=c++20 -fsyntax-only -verify %s + +#include "Inputs/std-coroutine.h" + +struct Awaiter { + int Value; + + bool await_ready(); + void await_suspend(std::coroutine_handle<>); + int await_resume(); +}; + +struct Task { + struct promise_type { + Task get_return_object(); + std::suspend_never initial_suspend() noexcept; + std::suspend_never final_suspend() noexcept; + Awaiter yield_value(int Value); + void return_void(); + void unhandled_exception(); + }; +}; + +template <int... Values> +Task yieldPack() { + ((void)(co_yield Values), ...); +} + +template Task yieldPack<1, 2, 3>(); +template Task yieldPack<>(); + +template <int... Values> +Task awaitPack() { + ((void)(co_await Awaiter{Values}), ...); +} + +template Task awaitPack<1, 2, 3>(); +template Task awaitPack<>(); + +template <int... Values> +Task unexpandedYield() { + co_yield Values; // expected-error {{expression contains unexpanded parameter pack 'Values'}} +} + +template <int... Values> +Task unexpandedAwait() { + co_await Awaiter{Values}; // expected-error {{expression contains unexpanded parameter pack 'Values'}} +} diff --git a/clang/test/SemaTemplate/opaque-value-pack-expansion.cpp b/clang/test/SemaTemplate/opaque-value-pack-expansion.cpp new file mode 100644 index 00000000000000..6a0861c84deb71 --- /dev/null +++ b/clang/test/SemaTemplate/opaque-value-pack-expansion.cpp @@ -0,0 +1,15 @@ +// RUN: %clang_cc1 -std=gnu++17 -fsyntax-only -verify %s + +template <typename... T> +void conditionalPack(T... Values) { + ((void)(Values ?: 0), ...); +} + +template void conditionalPack<int, int, int>(int, int, int); + +template <typename... T> +void unexpandedPack(T... Values) { + (void)(Values ?: 0); // expected-error {{expression contains unexpanded parameter pack 'Values'}} +} + +template void unexpandedPack<int, int, int>(int, int, int); >From 7bee81e972c3b756e5b9b9e827994baa4578e047 Mon Sep 17 00:00:00 2001 From: Kunal Dubey <[email protected]> Date: Mon, 2 Nov 2026 20:17:17 +0530 Subject: [PATCH 2/4] [Clang] Added Release Note --- clang/docs/ReleaseNotes.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/clang/docs/ReleaseNotes.md b/clang/docs/ReleaseNotes.md index 52fa928443f347..96931c6043b1ae 100644 --- a/clang/docs/ReleaseNotes.md +++ b/clang/docs/ReleaseNotes.md @@ -1038,6 +1038,9 @@ documentation](CIR/index.md) for more information regarding ClangIR's status and dependent `co_return` operand that inits to `void`, instead of using `promise.return_void()`. (#GH218368) +- Fixed a crash when `co_yield`, `co_await`, or GNU `?:` expressions used + parameter packs. (#GH162198) + - Fixed merging of lambdas across modules in the case where neither lambda is imported from an AST file. (#GH214560) >From e5724203d892237d623bac677c8afa82c54e33da Mon Sep 17 00:00:00 2001 From: Kunal Dubey <[email protected]> Date: Mon, 2 Nov 2026 23:06:11 +0530 Subject: [PATCH 3/4] [Clang] Changed the Semantic inheritance expression for OpaqueValueExpr --- clang/lib/AST/ComputeDependence.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang/lib/AST/ComputeDependence.cpp b/clang/lib/AST/ComputeDependence.cpp index 6a65b417a4c758..bc1060d16c6351 100644 --- a/clang/lib/AST/ComputeDependence.cpp +++ b/clang/lib/AST/ComputeDependence.cpp @@ -30,7 +30,7 @@ ExprDependence clang::computeDependence(OpaqueValueExpr *E) { // An OpaqueValueExpr has no syntactic children, so it does not contain an // unexpanded pack even if its source does. if (auto *S = E->getSourceExpr()) - D |= S->getDependence() & ~ExprDependence::UnexpandedPack; + D |= Dependence(S->getDependence()).semantic().expr(); assert(!(D & ExprDependence::UnexpandedPack)); return D; } >From 9ade97e9ecea825fae784a77e96430345084c212 Mon Sep 17 00:00:00 2001 From: Kunal Dubey <[email protected]> Date: Tue, 3 Nov 2026 10:30:40 +0530 Subject: [PATCH 4/4] [Clang] Cleanup for test files --- .../CXX/temp/temp.decls/temp.variadic/p5.cpp | 16 +++++++ .../test/SemaCXX/coroutine-pack-expansion.cpp | 48 ------------------- .../opaque-value-pack-expansion.cpp | 15 ------ 3 files changed, 16 insertions(+), 63 deletions(-) delete mode 100644 clang/test/SemaCXX/coroutine-pack-expansion.cpp delete mode 100644 clang/test/SemaTemplate/opaque-value-pack-expansion.cpp diff --git a/clang/test/CXX/temp/temp.decls/temp.variadic/p5.cpp b/clang/test/CXX/temp/temp.decls/temp.variadic/p5.cpp index 16e668e971a214..3648fc842321c0 100644 --- a/clang/test/CXX/temp/temp.decls/temp.variadic/p5.cpp +++ b/clang/test/CXX/temp/temp.decls/temp.variadic/p5.cpp @@ -152,6 +152,22 @@ void test_unexpanded_in_exprs() { // FIXME: continue this... } +#if __cplusplus >= 201703L +namespace GH162198 { +template <typename... T> +void conditionalPack(T... Values) { + ((void)(Values ?: 0), ...); +} + +template void conditionalPack<int, int, int>(int, int, int); + +template <typename... T> +void unexpandedConditionalPack(T... Values) { + (void)(Values ?: 0); // expected-error {{expression contains unexpanded parameter pack 'Values'}} +} +} // namespace GH162198 +#endif + template<typename ... Types> void TestPPNameFunc(int i) { f(static_cast<Types>(i)); // expected-error{{expression contains unexpanded parameter pack 'Types'}} diff --git a/clang/test/SemaCXX/coroutine-pack-expansion.cpp b/clang/test/SemaCXX/coroutine-pack-expansion.cpp deleted file mode 100644 index a2478c8975211a..00000000000000 --- a/clang/test/SemaCXX/coroutine-pack-expansion.cpp +++ /dev/null @@ -1,48 +0,0 @@ -// RUN: %clang_cc1 -std=c++20 -fsyntax-only -verify %s - -#include "Inputs/std-coroutine.h" - -struct Awaiter { - int Value; - - bool await_ready(); - void await_suspend(std::coroutine_handle<>); - int await_resume(); -}; - -struct Task { - struct promise_type { - Task get_return_object(); - std::suspend_never initial_suspend() noexcept; - std::suspend_never final_suspend() noexcept; - Awaiter yield_value(int Value); - void return_void(); - void unhandled_exception(); - }; -}; - -template <int... Values> -Task yieldPack() { - ((void)(co_yield Values), ...); -} - -template Task yieldPack<1, 2, 3>(); -template Task yieldPack<>(); - -template <int... Values> -Task awaitPack() { - ((void)(co_await Awaiter{Values}), ...); -} - -template Task awaitPack<1, 2, 3>(); -template Task awaitPack<>(); - -template <int... Values> -Task unexpandedYield() { - co_yield Values; // expected-error {{expression contains unexpanded parameter pack 'Values'}} -} - -template <int... Values> -Task unexpandedAwait() { - co_await Awaiter{Values}; // expected-error {{expression contains unexpanded parameter pack 'Values'}} -} diff --git a/clang/test/SemaTemplate/opaque-value-pack-expansion.cpp b/clang/test/SemaTemplate/opaque-value-pack-expansion.cpp deleted file mode 100644 index 6a0861c84deb71..00000000000000 --- a/clang/test/SemaTemplate/opaque-value-pack-expansion.cpp +++ /dev/null @@ -1,15 +0,0 @@ -// RUN: %clang_cc1 -std=gnu++17 -fsyntax-only -verify %s - -template <typename... T> -void conditionalPack(T... Values) { - ((void)(Values ?: 0), ...); -} - -template void conditionalPack<int, int, int>(int, int, int); - -template <typename... T> -void unexpandedPack(T... Values) { - (void)(Values ?: 0); // expected-error {{expression contains unexpanded parameter pack 'Values'}} -} - -template void unexpandedPack<int, int, int>(int, int, int); _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
