https://github.com/AaronBallman updated https://github.com/llvm/llvm-project/pull/70341
>From f068b471efa81d60d1d6e2c98da56be58958a015 Mon Sep 17 00:00:00 2001 From: Aaron Ballman <aa...@aaronballman.com> Date: Thu, 26 Oct 2023 10:53:06 -0400 Subject: [PATCH 1/2] Diagnose use of VLAs in a coroutine Fixes https://github.com/llvm/llvm-project/issues/65858 --- .../clang/Basic/DiagnosticSemaKinds.td | 2 ++ clang/include/clang/Sema/ScopeInfo.h | 8 +++++ clang/lib/Sema/SemaCoroutine.cpp | 5 ++++ clang/lib/Sema/SemaType.cpp | 18 ++++++++---- clang/test/SemaCXX/coroutine-vla.cpp | 29 +++++++++++++++++++ 5 files changed, 56 insertions(+), 6 deletions(-) create mode 100644 clang/test/SemaCXX/coroutine-vla.cpp diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index a673ce726d6c220..453bd8a9a340425 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -166,6 +166,8 @@ def ext_vla_folded_to_constant : ExtWarn< InGroup<GNUFoldingConstant>; def err_vla_unsupported : Error< "variable length arrays are not supported for %select{the current target|'%1'}0">; +def err_vla_in_coroutine_unsupported : Error< + "variable length arrays in a coroutine are not supported">; def note_vla_unsupported : Note< "variable length arrays are not supported for the current target">; diff --git a/clang/include/clang/Sema/ScopeInfo.h b/clang/include/clang/Sema/ScopeInfo.h index 02b22af89ff035d..b2f6e3289f41fce 100644 --- a/clang/include/clang/Sema/ScopeInfo.h +++ b/clang/include/clang/Sema/ScopeInfo.h @@ -189,6 +189,9 @@ class FunctionScopeInfo { /// First SEH '__try' statement in the current function. SourceLocation FirstSEHTryLoc; + /// First use of a VLA within the current function. + SourceLocation FirstVLALoc; + private: /// Used to determine if errors occurred in this function or block. DiagnosticErrorTrap ErrorTrap; @@ -473,6 +476,11 @@ class FunctionScopeInfo { FirstSEHTryLoc = TryLoc; } + void setHasVLA(SourceLocation VLALoc) { + if (FirstVLALoc.isInvalid()) + FirstVLALoc = VLALoc; + } + bool NeedsScopeChecking() const { return !HasDroppedStmt && (HasIndirectGoto || HasMustTail || (HasBranchProtectedScope && HasBranchIntoScope)); diff --git a/clang/lib/Sema/SemaCoroutine.cpp b/clang/lib/Sema/SemaCoroutine.cpp index d2b0922a4bb9c4c..e1f3b5acb3cadec 100644 --- a/clang/lib/Sema/SemaCoroutine.cpp +++ b/clang/lib/Sema/SemaCoroutine.cpp @@ -1198,6 +1198,11 @@ void Sema::CheckCompletedCoroutineBody(FunctionDecl *FD, Stmt *&Body) { if (FD->hasAttr<AlwaysInlineAttr>()) Diag(FD->getLocation(), diag::warn_always_inline_coroutine); + // We don't allow use of VLAs within a coroutine, so diagnose if we've seen + // a VLA in the body of this function. + if (Fn->FirstVLALoc.isValid()) + Diag(Fn->FirstVLALoc, diag::err_vla_in_coroutine_unsupported); + // [stmt.return.coroutine]p1: // A coroutine shall not enclose a return statement ([stmt.return]). if (Fn->FirstReturnLoc.isValid()) { diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp index 28b81c1768a3004..dea77fae4cadb59 100644 --- a/clang/lib/Sema/SemaType.cpp +++ b/clang/lib/Sema/SemaType.cpp @@ -2706,12 +2706,18 @@ QualType Sema::BuildArrayType(QualType T, ArrayType::ArraySizeModifier ASM, } } - if (T->isVariableArrayType() && !Context.getTargetInfo().isVLASupported()) { - // CUDA device code and some other targets don't support VLAs. - bool IsCUDADevice = (getLangOpts().CUDA && getLangOpts().CUDAIsDevice); - targetDiag(Loc, - IsCUDADevice ? diag::err_cuda_vla : diag::err_vla_unsupported) - << (IsCUDADevice ? CurrentCUDATarget() : 0); + if (T->isVariableArrayType()) { + if (!Context.getTargetInfo().isVLASupported()) { + // CUDA device code and some other targets don't support VLAs. + bool IsCUDADevice = (getLangOpts().CUDA && getLangOpts().CUDAIsDevice); + targetDiag(Loc, + IsCUDADevice ? diag::err_cuda_vla : diag::err_vla_unsupported) + << (IsCUDADevice ? CurrentCUDATarget() : 0); + } else if (sema::FunctionScopeInfo *FSI = getCurFunction()) { + // VLAs are supported on this target, but we may need to do delayed + // checking that the VLA is not being used within a coroutine. + FSI->setHasVLA(Loc); + } } // If this is not C99, diagnose array size modifiers on non-VLAs. diff --git a/clang/test/SemaCXX/coroutine-vla.cpp b/clang/test/SemaCXX/coroutine-vla.cpp new file mode 100644 index 000000000000000..176e35f346e2b45 --- /dev/null +++ b/clang/test/SemaCXX/coroutine-vla.cpp @@ -0,0 +1,29 @@ +// RUN: %clang_cc1 %s -std=c++20 -fsyntax-only -Wno-vla-cxx-extension -verify +#include "Inputs/std-coroutine.h" + +struct promise; + +struct coroutine : std::coroutine_handle<promise> { + using promise_type = ::promise; +}; + +struct promise +{ + coroutine get_return_object(); + std::suspend_always initial_suspend() noexcept; + std::suspend_always final_suspend() noexcept; + void return_void(); + void unhandled_exception(); +}; + +coroutine foo(int n) { + int array[n]; // expected-error {{variable length arrays in a coroutine are not supported}} + co_return; +} + +void lambda() { + [](int n) -> coroutine { + int array[n]; // expected-error {{variable length arrays in a coroutine are not supported}} + co_return; + }(10); +} >From 123789ebe3a3c01db54e77ed7c95f47775375f53 Mon Sep 17 00:00:00 2001 From: Aaron Ballman <aa...@aaronballman.com> Date: Thu, 26 Oct 2023 11:47:17 -0400 Subject: [PATCH 2/2] Update comment + add release note --- clang/docs/ReleaseNotes.rst | 4 ++++ clang/lib/Sema/SemaCoroutine.cpp | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index c0514e5b70783b6..3af16e40a96b79d 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -629,6 +629,10 @@ Bug Fixes to C++ Support (`#46200 <https://github.com/llvm/llvm-project/issues/46200>`_) (`#57812 <https://github.com/llvm/llvm-project/issues/57812>`_) +- Diagnose use of a variable-length array in a coroutine. The design of + coroutines is such that it is not possible to support VLA use. Fixes: + (`#65858 <https://github.com/llvm/llvm-project/issues/65858>`_) + Bug Fixes to AST Handling ^^^^^^^^^^^^^^^^^^^^^^^^^ - Fixed an import failure of recursive friend class template. diff --git a/clang/lib/Sema/SemaCoroutine.cpp b/clang/lib/Sema/SemaCoroutine.cpp index e1f3b5acb3cadec..cfaa93fbea4dd37 100644 --- a/clang/lib/Sema/SemaCoroutine.cpp +++ b/clang/lib/Sema/SemaCoroutine.cpp @@ -1198,8 +1198,8 @@ void Sema::CheckCompletedCoroutineBody(FunctionDecl *FD, Stmt *&Body) { if (FD->hasAttr<AlwaysInlineAttr>()) Diag(FD->getLocation(), diag::warn_always_inline_coroutine); - // We don't allow use of VLAs within a coroutine, so diagnose if we've seen - // a VLA in the body of this function. + // The design of coroutines means we cannot allow use of VLAs within one, so + // diagnose if we've seen a VLA in the body of this function. if (Fn->FirstVLALoc.isValid()) Diag(Fn->FirstVLALoc, diag::err_vla_in_coroutine_unsupported); _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits