diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index abe300ecc5431..d15278bce5a6b 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -19528,16 +19528,6 @@ static bool captureInLambda(LambdaScopeInfo *LSI, ValueDecl *Var, ByRef = (LSI->ImpCaptureStyle == LambdaScopeInfo::ImpCap_LambdaByref); } - BindingDecl *BD = dyn_cast(Var); - // FIXME: We should support capturing structured bindings in OpenMP. - if (!Invalid && BD && S.LangOpts.OpenMP) { - if (BuildAndDiagnose) { - S.Diag(Loc, diag::err_capture_binding_openmp) << Var; - S.Diag(Var->getLocation(), diag::note_entity_declared_at) << Var; - } - Invalid = true; - } - if (BuildAndDiagnose && S.Context.getTargetInfo().getTriple().isWasm() && CaptureType.getNonReferenceType().isWebAssemblyReferenceType()) { S.Diag(Loc, diag::err_wasm_ca_reference) << 0; @@ -19879,6 +19869,14 @@ bool Sema::tryCaptureVariable( // just break here. Similarly, global variables that are captured in a // target region should not be captured outside the scope of the region. if (RSI->CapRegionKind == CR_OpenMP) { + // FIXME: We should support capturing structured bindings in OpenMP. + if (isa(Var)) { + if (BuildAndDiagnose) { + Diag(ExprLoc, diag::err_capture_binding_openmp) << Var; + Diag(Var->getLocation(), diag::note_entity_declared_at) << Var; + } + return true; + } OpenMPClauseKind IsOpenMPPrivateDecl = isOpenMPPrivateDecl( Var, RSI->OpenMPLevel, RSI->OpenMPCaptureLevel); // If the variable is private (i.e. not captured) and has variably diff --git a/clang/test/SemaCXX/decomposition-openmp.cpp b/clang/test/SemaCXX/decomposition-openmp.cpp index 28afc39800399..2185f3db83d4e 100644 --- a/clang/test/SemaCXX/decomposition-openmp.cpp +++ b/clang/test/SemaCXX/decomposition-openmp.cpp @@ -1,13 +1,32 @@ - // RUN: %clang_cc1 -fsyntax-only -verify -std=c++20 -fopenmp %s -// FIXME: OpenMP should support capturing structured bindings +// Okay, not an OpenMP capture. auto f() { int i[2] = {}; - auto [a, b] = i; // expected-note 2{{declared here}} + auto [a, b] = i; return [=, &a] { - // expected-error@-1 {{capturing a structured binding is not yet supported in OpenMP}} return a + b; - // expected-error@-1 {{capturing a structured binding is not yet supported in OpenMP}} }; } + +// Okay, not an OpenMP capture. +void foo(int); +void g() { + #pragma omp parallel + { + int i[2] = {}; + auto [a, b] = i; + auto L = [&] { foo(a+b); }; + } +} + +// FIXME: OpenMP should support capturing structured bindings +void h() { + int i[2] = {}; + auto [a, b] = i; // expected-note 2{{declared here}} + #pragma omp parallel + { + // expected-error@+1 2{{capturing a structured binding is not yet supported in OpenMP}} + foo(a + b); + } +}