@@ -623,6 +623,7 @@ static mlir::Value emitCXXNewAllocSize(CIRGenFunction &CGF, const CXXNewExpr *e,
623
623
mlir::cast<cir::IntAttr>(constNumElements).getValue ();
624
624
625
625
unsigned numElementsWidth = count.getBitWidth ();
626
+ bool hasAnyOverflow = false ;
626
627
627
628
// The equivalent code in CodeGen/CGExprCXX.cpp handles these cases as
628
629
// overflow, but they should never happen. The size argument is implicitly
@@ -653,10 +654,22 @@ static mlir::Value emitCXXNewAllocSize(CIRGenFunction &CGF, const CXXNewExpr *e,
653
654
654
655
// Add in the cookie, and check whether it's overflowed.
655
656
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;
657
664
}
658
665
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
+ }
660
673
} else {
661
674
// TODO: Handle the variable size case
662
675
llvm_unreachable (" NYI" );
@@ -858,6 +871,46 @@ void CIRGenFunction::emitNewArrayInitializer(
858
871
if (!E->hasInitializer ())
859
872
return ;
860
873
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
+
861
914
llvm_unreachable (" NYI" );
862
915
}
863
916
@@ -1088,7 +1141,8 @@ mlir::Value CIRGenFunction::emitCXXNewExpr(const CXXNewExpr *E) {
1088
1141
++ParamsToSkip;
1089
1142
1090
1143
if (allocSize != allocSizeWithoutCookie) {
1091
- llvm_unreachable (" NYI" );
1144
+ CharUnits cookieAlign = getSizeAlign (); // FIXME: Ask the ABI.
1145
+ allocAlign = std::max (allocAlign, cookieAlign);
1092
1146
}
1093
1147
1094
1148
// The allocation alignment may be passed as the second argument.
@@ -1186,7 +1240,9 @@ mlir::Value CIRGenFunction::emitCXXNewExpr(const CXXNewExpr *E) {
1186
1240
assert ((allocSize == allocSizeWithoutCookie) ==
1187
1241
CalculateCookiePadding (*this , E).isZero ());
1188
1242
if (allocSize != allocSizeWithoutCookie) {
1189
- llvm_unreachable (" NYI" );
1243
+ assert (E->isArray ());
1244
+ allocation = CGM.getCXXABI ().initializeArrayCookie (
1245
+ *this , allocation, numElements, E, allocType);
1190
1246
}
1191
1247
1192
1248
mlir::Type elementTy;
0 commit comments