================
@@ -3589,6 +3589,50 @@ static bool
canEmitSpuriousReferenceToVariable(CodeGenFunction &CGF,
}
}
+/// Emit an LValue for a structured binding captured in an OpenMP region.
+/// Handles extracting individual bindings from the captured decomposed
+/// declaration (struct fields, array elements, etc.).
+LValue CodeGenFunction::EmitOMPCapturedBindingLValue(const BindingDecl *BD) {
+ assert(CapturedStmtInfo &&
+ CapturedStmtInfo->getKind() == CapturedRegionKind::CR_OpenMP &&
+ CGM.getLangOpts().OpenMP);
+ auto *DD = cast<VarDecl>(BD->getDecomposedDecl());
+ QualType AggregType = DD->getType();
+ if (AggregType->isReferenceType())
+ AggregType = AggregType->getPointeeType();
+ DeclarationNameInfo NameInfo(DD->getDeclName(), SourceLocation());
+ DeclRefExpr *DRE = DeclRefExpr::Create(
+ getContext(), NestedNameSpecifierLoc(), SourceLocation(), DD,
+ /*RefersToEnclosingVariableOrCapture=*/true, NameInfo, AggregType,
+ VK_LValue);
+ LValue CapLVal = EmitLValue(DRE);
+ QualType CanonType = AggregType.getCanonicalType();
+ llvm::Type *StructTy = CGM.getTypes().ConvertTypeForMem(CanonType);
+ Address Addr = CapLVal.getAddress();
+ if (Addr.getElementType() != StructTy) {
+ Addr = Addr.withElementType(StructTy);
+ CapLVal = MakeAddrLValue(Addr, CanonType, CapLVal.getBaseInfo(),
+ CapLVal.getTBAAInfo());
+ }
+ // Extract the specific binding from the decomposed object.
+ Expr *BindingExpr = BD->getBinding()->IgnoreImplicit();
+ if (auto *ME = dyn_cast<MemberExpr>(BindingExpr)) {
+ // Struct/union: access field.
+ FieldDecl *Field = cast<FieldDecl>(ME->getMemberDecl());
+ return EmitLValueForField(CapLVal, Field);
+ }
+ if (dyn_cast<ArraySubscriptExpr>(BindingExpr)) {
+ // Array binding - access element.
+ return EmitLValue(BD->getBinding(), NotKnownNonNull);
+ }
+
+ // TODO: Tuple bindings (std::tuple, std::pair via tuple protocol)
+ // use hidden temporary variables that aren't captured in OpenMP
+ // regions. Need to re-emit the get<N>() call on the captured tuple
+ // base object.
+ llvm_unreachable("Unexpected structured binding type in OpenMP");
----------------
alexey-bataev wrote:
This is a hard crash on legal C++ code. `llvm_unreachable` is undefined
behavior in release builds and a trap in debug builds. For tuple-like bindings
(using `tuple_size`/`tuple_element`/`get<N>()`, e.g. `std::tuple`, `std::pair`,
`std::array`), `BD->getBinding()->IgnoreImplicit()` is a `DeclRefExpr` to an
implicit holding `VarDecl`, which matches neither `MemberExpr` nor
`ArraySubscriptExpr`. Result: any user that captures a `std::pair` or
`std::tuple` binding in an OpenMP region crashes the compiler. The release
notes claim 'Tuple-like bindings ... will produce a compilation error', but no
diagnostic is emitted. Either reject in Sema (preferred, restoring
`err_capture_binding_openmp` for the tuple case) or report a proper diagnostic
via `CGM.getDiags()` here. A test case using `std::tuple` must be added (it
currently asserts/crashes).
https://github.com/llvm/llvm-project/pull/190832
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits