================
@@ -1152,11 +1154,35 @@ bool CodeGenFunction::EmitOMPFirstprivateClause(const 
OMPExecutableDirective &D,
     const auto *IRef = C->varlist_begin();
     const auto *InitsRef = C->inits().begin();
     for (const Expr *IInit : C->private_copies()) {
-      const auto *OrigVD = cast<VarDecl>(cast<DeclRefExpr>(*IRef)->getDecl());
+      const auto *OrigDecl = cast<DeclRefExpr>(*IRef)->getDecl();
+      const VarDecl *OrigVD = dyn_cast<VarDecl>(OrigDecl);
+      const auto *VD = cast<VarDecl>(cast<DeclRefExpr>(IInit)->getDecl());
+
+      if (const auto *BD = dyn_cast<BindingDecl>(OrigDecl)) {
+        Address PrivateAddr = CreateMemTemp(VD->getType(), VD->getName());
+        DeclRefExpr DRE(getContext(), const_cast<BindingDecl *>(BD),
+                        /*RefersToEnclosingVariableOrCapture=*/true,
+                        BD->getType(), VK_LValue, (*IRef)->getExprLoc());
+        LValue OriginalLVal = EmitLValue(&DRE);
+        RValue OrigValue =
+            EmitLoadOfLValue(OriginalLVal, (*IRef)->getExprLoc());
+        EmitStoreThroughLValue(OrigValue,
+                               MakeAddrLValue(PrivateAddr, VD->getType()));
----------------
alexey-bataev wrote:

EmitLoadOfLValue + EmitStoreThroughLValue is a bitwise copy. For 
non-trivially-copyable element types (e.g., a struct member with a user-defined 
copy constructor), this bypasses the copy constructor entirely, producing 
undefined behavior. The standard firstprivate path (below, for VarDecl) uses 
EmitCopyInit which handles non-trivial types.

Also, the tests with user-defined copying are required

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