@@ -623,6 +623,7 @@ static mlir::Value emitCXXNewAllocSize(CIRGenFunction &CGF, const CXXNewExpr *e,
623623 mlir::cast<cir::IntAttr>(constNumElements).getValue ();
624624
625625 unsigned numElementsWidth = count.getBitWidth ();
626+ bool hasAnyOverflow = false ;
626627
627628 // The equivalent code in CodeGen/CGExprCXX.cpp handles these cases as
628629 // overflow, but they should never happen. The size argument is implicitly
@@ -653,10 +654,22 @@ static mlir::Value emitCXXNewAllocSize(CIRGenFunction &CGF, const CXXNewExpr *e,
653654
654655 // Add in the cookie, and check whether it's overflowed.
655656 if (cookieSize != 0 ) {
656- llvm_unreachable (" NYI" );
657+ // Save the current size without a cookie. This shouldn't be
658+ // used if there was overflow.
659+ sizeWithoutCookie = CGF.getBuilder ().getConstInt (
660+ Loc, allocationSize.zextOrTrunc (sizeWidth));
661+
662+ allocationSize = allocationSize.uadd_ov (cookieSize, overflow);
663+ hasAnyOverflow |= overflow;
657664 }
658665
659- size = CGF.getBuilder ().getConstInt (Loc, allocationSize);
666+ // On overflow, produce a -1 so operator new will fail.
667+ if (hasAnyOverflow) {
668+ size =
669+ CGF.getBuilder ().getConstInt (Loc, llvm::APInt::getAllOnes (sizeWidth));
670+ } else {
671+ size = CGF.getBuilder ().getConstInt (Loc, allocationSize);
672+ }
660673 } else {
661674 // TODO: Handle the variable size case
662675 llvm_unreachable (" NYI" );
@@ -858,6 +871,46 @@ void CIRGenFunction::emitNewArrayInitializer(
858871 if (!E->hasInitializer ())
859872 return ;
860873
874+ Address CurPtr = BeginPtr;
875+
876+ unsigned InitListElements = 0 ;
877+
878+ const Expr *Init = E->getInitializer ();
879+ CleanupDeactivationScope deactivation (*this );
880+
881+ const InitListExpr *ILE = dyn_cast<InitListExpr>(Init);
882+ if (ILE) {
883+ llvm_unreachable (" NYI" );
884+ }
885+
886+ // If all elements have already been initialized, skip any further
887+ // initialization.
888+ auto ConstOp = dyn_cast<cir::ConstantOp>(NumElements.getDefiningOp ());
889+ if (ConstOp) {
890+ auto ConstIntAttr = mlir::dyn_cast<cir::IntAttr>(ConstOp.getValue ());
891+ // Just skip out if the constant count is zero.
892+ if (ConstIntAttr && ConstIntAttr.getUInt () <= InitListElements)
893+ return ;
894+ }
895+
896+ assert (Init && " have trailing elements to initialize but no initializer" );
897+
898+ // If this is a constructor call, try to optimize it out, and failing that
899+ // emit a single loop to initialize all remaining elements.
900+ if (const CXXConstructExpr *CCE = dyn_cast<CXXConstructExpr>(Init)) {
901+ CXXConstructorDecl *Ctor = CCE->getConstructor ();
902+ if (Ctor->isTrivial ()) {
903+ // If new expression did not specify value-initialization, then there
904+ // is no initialization.
905+ if (!CCE->requiresZeroInitialization () || Ctor->getParent ()->isEmpty ())
906+ return ;
907+
908+ llvm_unreachable (" NYI" );
909+ }
910+
911+ llvm_unreachable (" NYI" );
912+ }
913+
861914 llvm_unreachable (" NYI" );
862915}
863916
@@ -1088,7 +1141,8 @@ mlir::Value CIRGenFunction::emitCXXNewExpr(const CXXNewExpr *E) {
10881141 ++ParamsToSkip;
10891142
10901143 if (allocSize != allocSizeWithoutCookie) {
1091- llvm_unreachable (" NYI" );
1144+ CharUnits cookieAlign = getSizeAlign (); // FIXME: Ask the ABI.
1145+ allocAlign = std::max (allocAlign, cookieAlign);
10921146 }
10931147
10941148 // The allocation alignment may be passed as the second argument.
@@ -1186,7 +1240,9 @@ mlir::Value CIRGenFunction::emitCXXNewExpr(const CXXNewExpr *E) {
11861240 assert ((allocSize == allocSizeWithoutCookie) ==
11871241 CalculateCookiePadding (*this , E).isZero ());
11881242 if (allocSize != allocSizeWithoutCookie) {
1189- llvm_unreachable (" NYI" );
1243+ assert (E->isArray ());
1244+ allocation = CGM.getCXXABI ().initializeArrayCookie (
1245+ *this , allocation, numElements, E, allocType);
11901246 }
11911247
11921248 mlir::Type elementTy;
0 commit comments