================
@@ -3595,6 +3595,75 @@ 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 && "Expected to be inside a captured region");
+  assert(CapturedStmtInfo->getKind() == CapturedRegionKind::CR_OpenMP &&
+         "Expected OpenMP captured region");
+  assert(CGM.getLangOpts().OpenMP && "Expected OpenMP to be enabled");
+
+  if (auto It = LocalDeclMap.find(BD->getCanonicalDecl());
+      It != LocalDeclMap.end())
+    return MakeAddrLValue(It->second, BD->getType());
+
+  const auto *DD = cast<VarDecl>(BD->getDecomposedDecl());
+
+  // Check if the original variable (what DD decomposes) has been mapped.
+  // If so, use the original variable instead of DD to avoid capturing DD.
+  const VarDecl *TargetDecl = DD;
+  if (const auto *DecompDecl = dyn_cast<DecompositionDecl>(DD)) {
+    if (const VarDecl *OrigVar = DecompDecl->getOriginalVar().Var) {
+      auto It = LocalDeclMap.find(OrigVar->getCanonicalDecl());
+      if (It != LocalDeclMap.end())
+        // Original variable is mapped, use it instead.
+        TargetDecl = OrigVar;
+    }
+  }
+
+  // Use getNonReferenceType() because we need the actual object type, not the
+  // reference type. DeclRefExpr with VK_LValue requires a non-reference type
+  // (AST invariant). EmitDeclRefLValue will load any reference for us.
+  QualType DREType = TargetDecl->getType().getNonReferenceType();
+  DeclRefExpr DRE(getContext(), const_cast<VarDecl *>(TargetDecl),
+                  /*RefersToEnclosingVariableOrCapture=*/true, DREType,
+                  VK_LValue, SourceLocation());
+  LValue BaseLVal = EmitDeclRefLValue(&DRE);
+
+  // Ensure the Address has the correct element type for DD's type.
+  // EmitDeclRefLValue might return an address with a different element type
+  // if TargetDecl != DD or if reference unwrapping occurred.
+  Address BaseAddr = BaseLVal.getAddress();
+  QualType DDType = DD->getType();
----------------
zahiraam wrote:

Using` .getNonReferenceType()` causes a crash with reference bindings:          
          
                                                                                
          
  `auto& [a, b] = p;  // DD has reference type Point&`
                                                                                
          
  The assertion failure in `initializeSimpleLValue` indicates type mismatch. 
When           
  `DD->getType()` is a reference, `EmitDeclRefLValue` already unwraps it and 
returns an address to the underlying object. Using `.getNonReferenceType()` 
then creates a mismatch between the address type and what LLVM expects.  Should 
we keep the original `DD->getType()` without `.getNonReferenceType()`?


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