================
@@ -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())
----------------
alexey-bataev wrote:

Stripping the reference here breaks the regular `VarDecl` path's reference 
handling. For `auto& [m, n] = p;`, the DD's type is `Point&`. Stripping it 
before constructing the DRE means the DRE has type `Point` while 
`VD->getType()` (inside `EmitDeclRefLValue`) is `Point&`. The standard path 
checks `VD->getType()->isReferenceType()` and calls 
`EmitLoadOfReferenceLValue`, which is why the `test_reference_binding` IR shows 
the extra load/store/load round trip. Pass through the natural reference type 
and let the existing emission handle it.

https://github.com/llvm/llvm-project/pull/190832
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to