================
@@ -24377,6 +24378,60 @@ VarDecl
*SemaOpenMP::ActOnOpenMPDeclareReductionInitializerStart(Scope *S,
void SemaOpenMP::ActOnOpenMPDeclareReductionInitializerEnd(
Decl *D, Expr *Initializer, VarDecl *OmpPrivParm) {
auto *DRD = cast<OMPDeclareReductionDecl>(D);
+
+ // For non-trivial types with user initializers, build an AST that
+ // includes default construction first to initialize members before user
+ // initializer. This must be done BEFORE popping contexts.
+ if (Initializer && !DRD->getDeclContext()->isDependentContext()) {
+ QualType ReductionType = DRD->getType();
+ if (const auto *RD = ReductionType->getAsCXXRecordDecl()) {
+ CXXConstructorDecl *DefaultCtor =
+ SemaRef.LookupDefaultConstructor(const_cast<CXXRecordDecl *>(RD));
+ if (DefaultCtor && !DefaultCtor->isDeleted() &&
+ !DefaultCtor->isTrivial()) {
+ // Build default arguments for constructor parameters.
+ SmallVector<Expr *, 4> CtorArgs;
+ for (unsigned I : llvm::seq(DefaultCtor->getNumParams())) {
+ const ParmVarDecl *Param = DefaultCtor->getParamDecl(I);
+ if (Param->hasDefaultArg()) {
+ ExprResult DefArg = SemaRef.BuildCXXDefaultArgExpr(
+ D->getLocation(), DefaultCtor,
+ const_cast<ParmVarDecl *>(Param));
+ if (DefArg.isUsable())
+ CtorArgs.push_back(DefArg.get());
+ }
+ }
+
+ // Build constructor expression targeting omp_priv.
+ ExprResult CtorCall = SemaRef.BuildCXXConstructExpr(
+ D->getLocation(), ReductionType, DefaultCtor,
+ /*Elidable=*/false, CtorArgs,
+ /*HadMultipleCandidates=*/false,
+ /*IsListInitialization=*/false,
+ /*IsStdInitListInitialization=*/false,
+ /*RequiresZeroInit=*/false, CXXConstructionKind::Complete,
+ SourceRange());
+
+ if (CtorCall.isUsable()) {
+ // Wrap constructor and user initializer in StmtExpr.
+ // Create CompoundStmt directly since we don't have an active
+ // scope.
+ SmallVector<Stmt *, 2> Stmts;
+ Stmts.push_back(CtorCall.get());
+ Stmts.push_back(Initializer);
+
+ CompoundStmt *CS =
+ CompoundStmt::Create(SemaRef.Context, Stmts, FPOptionsOverride(),
+ D->getLocation(), D->getLocation());
+
+ Initializer = new (SemaRef.Context) StmtExpr(
+ CS, SemaRef.Context.VoidTy, D->getLocation(), D->getLocation(),
+ /*TemplateDepth=*/0);
+ }
+ }
+ }
+ }
----------------
alexey-bataev wrote:
I would not do this, it is unsafe and unsound, use standard functions, like
AddInitializer or something like AddefaultInitializer(?), already used in this
file, do not try to build constructor call yourself, you're missing so many
corner cases/generate incorrect code
https://github.com/llvm/llvm-project/pull/219265
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits