================
@@ -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