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

Reply via email to