@@ -194,12 +194,12 @@ template <class Emitter> class StmtExprScope final {
194194template <class Emitter >
195195bool Compiler<Emitter>::VisitCastExpr(const CastExpr *CE) {
196196 const Expr *SubExpr = CE->getSubExpr ();
197- switch (CE->getCastKind ()) {
198197
199- case CK_LValueToRValue: {
200- if (DiscardResult)
201- return this ->discard (SubExpr);
198+ if (DiscardResult)
199+ return this ->delegate (SubExpr);
202200
201+ switch (CE->getCastKind ()) {
202+ case CK_LValueToRValue: {
203203 std::optional<PrimType> SubExprT = classify (SubExpr->getType ());
204204 // Prepare storage for the result.
205205 if (!Initializing && !SubExprT) {
@@ -253,9 +253,6 @@ bool Compiler<Emitter>::VisitCastExpr(const CastExpr *CE) {
253253
254254 case CK_UncheckedDerivedToBase:
255255 case CK_DerivedToBase: {
256- if (DiscardResult)
257- return this ->discard (SubExpr);
258-
259256 if (!this ->delegate (SubExpr))
260257 return false ;
261258
@@ -285,9 +282,6 @@ bool Compiler<Emitter>::VisitCastExpr(const CastExpr *CE) {
285282 }
286283
287284 case CK_BaseToDerived: {
288- if (DiscardResult)
289- return this ->discard (SubExpr);
290-
291285 if (!this ->delegate (SubExpr))
292286 return false ;
293287
@@ -302,17 +296,13 @@ bool Compiler<Emitter>::VisitCastExpr(const CastExpr *CE) {
302296 if (!SubExpr->getType ()->isFloatingType () ||
303297 !CE->getType ()->isFloatingType ())
304298 return false ;
305- if (DiscardResult)
306- return this ->discard (SubExpr);
307299 if (!this ->visit (SubExpr))
308300 return false ;
309301 const auto *TargetSemantics = &Ctx.getFloatSemantics (CE->getType ());
310302 return this ->emitCastFP (TargetSemantics, getRoundingMode (CE), CE);
311303 }
312304
313305 case CK_IntegralToFloating: {
314- if (DiscardResult)
315- return this ->discard (SubExpr);
316306 std::optional<PrimType> FromT = classify (SubExpr->getType ());
317307 if (!FromT)
318308 return false ;
@@ -327,8 +317,6 @@ bool Compiler<Emitter>::VisitCastExpr(const CastExpr *CE) {
327317
328318 case CK_FloatingToBoolean:
329319 case CK_FloatingToIntegral: {
330- if (DiscardResult)
331- return this ->discard (SubExpr);
332320
333321 std::optional<PrimType> ToT = classify (CE->getType ());
334322
@@ -352,9 +340,6 @@ bool Compiler<Emitter>::VisitCastExpr(const CastExpr *CE) {
352340 case CK_NullToMemberPointer: {
353341 if (!this ->discard (SubExpr))
354342 return false ;
355- if (DiscardResult)
356- return true ;
357-
358343 const Descriptor *Desc = nullptr ;
359344 const QualType PointeeType = CE->getType ()->getPointeeType ();
360345 if (!PointeeType.isNull ()) {
@@ -371,9 +356,6 @@ bool Compiler<Emitter>::VisitCastExpr(const CastExpr *CE) {
371356 }
372357
373358 case CK_PointerToIntegral: {
374- if (DiscardResult)
375- return this ->discard (SubExpr);
376-
377359 if (!this ->visit (SubExpr))
378360 return false ;
379361
@@ -399,8 +381,6 @@ bool Compiler<Emitter>::VisitCastExpr(const CastExpr *CE) {
399381 return false ;
400382 if (!this ->emitArrayDecay (CE))
401383 return false ;
402- if (DiscardResult)
403- return this ->emitPopPtr (CE);
404384 return true ;
405385 }
406386
@@ -412,9 +392,6 @@ bool Compiler<Emitter>::VisitCastExpr(const CastExpr *CE) {
412392 // FIXME: I think the discard is wrong since the int->ptr cast might cause a
413393 // diagnostic.
414394 PrimType T = classifyPrim (IntType);
415- if (DiscardResult)
416- return this ->emitPop (T, CE);
417-
418395 QualType PtrType = CE->getType ();
419396 const Descriptor *Desc;
420397 if (std::optional<PrimType> T = classify (PtrType->getPointeeType ()))
@@ -454,10 +431,6 @@ bool Compiler<Emitter>::VisitCastExpr(const CastExpr *CE) {
454431 return false ;
455432 return this ->emitInvalidCast (CastKind::Reinterpret, /* Fatal=*/ true , CE);
456433 }
457-
458- if (DiscardResult)
459- return this ->discard (SubExpr);
460-
461434 QualType SubExprTy = SubExpr->getType ();
462435 std::optional<PrimType> FromT = classify (SubExprTy);
463436 // Casts from integer/vector to vector.
@@ -493,8 +466,6 @@ bool Compiler<Emitter>::VisitCastExpr(const CastExpr *CE) {
493466 case CK_FixedPointToBoolean:
494467 case CK_BooleanToSignedIntegral:
495468 case CK_IntegralCast: {
496- if (DiscardResult)
497- return this ->discard (SubExpr);
498469 std::optional<PrimType> FromT = classify (SubExpr->getType ());
499470 std::optional<PrimType> ToT = classify (CE->getType ());
500471
@@ -546,8 +517,6 @@ bool Compiler<Emitter>::VisitCastExpr(const CastExpr *CE) {
546517
547518 case CK_IntegralComplexToBoolean:
548519 case CK_FloatingComplexToBoolean: {
549- if (DiscardResult)
550- return this ->discard (SubExpr);
551520 if (!this ->visit (SubExpr))
552521 return false ;
553522 return this ->emitComplexBoolCast (SubExpr);
@@ -585,9 +554,6 @@ bool Compiler<Emitter>::VisitCastExpr(const CastExpr *CE) {
585554 case CK_FloatingComplexToIntegralComplex: {
586555 assert (CE->getType ()->isAnyComplexType ());
587556 assert (SubExpr->getType ()->isAnyComplexType ());
588- if (DiscardResult)
589- return this ->discard (SubExpr);
590-
591557 if (!Initializing) {
592558 std::optional<unsigned > LocalIndex = allocateLocal (CE);
593559 if (!LocalIndex)
@@ -633,9 +599,6 @@ bool Compiler<Emitter>::VisitCastExpr(const CastExpr *CE) {
633599 assert (classify (SubExpr->getType ()));
634600 assert (CE->getType ()->isVectorType ());
635601
636- if (DiscardResult)
637- return this ->discard (SubExpr);
638-
639602 if (!Initializing) {
640603 std::optional<unsigned > LocalIndex = allocateLocal (CE);
641604 if (!LocalIndex)
@@ -3370,15 +3333,23 @@ bool Compiler<Emitter>::VisitCXXNewExpr(const CXXNewExpr *E) {
33703333
33713334 PrimType SizeT = classifyPrim (Stripped->getType ());
33723335
3336+ // Save evaluated array size to a variable.
3337+ unsigned ArrayLen = allocateLocalPrimitive (
3338+ Stripped, SizeT, /* IsConst=*/ false , /* IsExtended=*/ false );
3339+ if (!this ->visit (Stripped))
3340+ return false ;
3341+ if (!this ->emitSetLocal (SizeT, ArrayLen, E))
3342+ return false ;
3343+
33733344 if (PlacementDest) {
33743345 if (!this ->visit (PlacementDest))
33753346 return false ;
3376- if (!this ->visit (Stripped ))
3347+ if (!this ->emitGetLocal (SizeT, ArrayLen, E ))
33773348 return false ;
33783349 if (!this ->emitCheckNewTypeMismatchArray (SizeT, E, E))
33793350 return false ;
33803351 } else {
3381- if (!this ->visit (Stripped ))
3352+ if (!this ->emitGetLocal (SizeT, ArrayLen, E ))
33823353 return false ;
33833354
33843355 if (ElemT) {
@@ -3392,10 +3363,113 @@ bool Compiler<Emitter>::VisitCXXNewExpr(const CXXNewExpr *E) {
33923363 }
33933364 }
33943365
3395- if (Init && !this ->visitInitializer (Init))
3396- return false ;
3366+ if (Init) {
3367+ QualType InitType = Init->getType ();
3368+ size_t StaticInitElems = 0 ;
3369+ const Expr *DynamicInit = nullptr ;
3370+ if (const ConstantArrayType *CAT =
3371+ Ctx.getASTContext ().getAsConstantArrayType (InitType)) {
3372+ StaticInitElems = CAT->getZExtSize ();
3373+ if (!this ->visitInitializer (Init))
3374+ return false ;
33973375
3398- } else {
3376+ if (const auto *ILE = dyn_cast<InitListExpr>(Init);
3377+ ILE && ILE->hasArrayFiller ())
3378+ DynamicInit = ILE->getArrayFiller ();
3379+ }
3380+
3381+ // The initializer initializes a certain number of elements, S.
3382+ // However, the complete number of elements, N, might be larger than that.
3383+ // In this case, we need to get an initializer for the remaining elements.
3384+ // There are to cases:
3385+ // 1) For the form 'new Struct[n];', the initializer is a
3386+ // CXXConstructExpr and its type is an IncompleteArrayType.
3387+ // 2) For the form 'new Struct[n]{1,2,3}', the initializer is an
3388+ // InitListExpr and the initializer for the remaining elements
3389+ // is the array filler.
3390+
3391+ if (DynamicInit || InitType->isIncompleteArrayType ()) {
3392+ const Function *CtorFunc = nullptr ;
3393+ if (const auto *CE = dyn_cast<CXXConstructExpr>(Init)) {
3394+ CtorFunc = getFunction (CE->getConstructor ());
3395+ if (!CtorFunc)
3396+ return false ;
3397+ }
3398+
3399+ LabelTy EndLabel = this ->getLabel ();
3400+ LabelTy StartLabel = this ->getLabel ();
3401+
3402+ // In the nothrow case, the alloc above might have returned nullptr.
3403+ // Don't call any constructors that case.
3404+ if (IsNoThrow) {
3405+ if (!this ->emitDupPtr (E))
3406+ return false ;
3407+ if (!this ->emitNullPtr (0 , nullptr , E))
3408+ return false ;
3409+ if (!this ->emitEQPtr (E))
3410+ return false ;
3411+ if (!this ->jumpTrue (EndLabel))
3412+ return false ;
3413+ }
3414+
3415+ // Create loop variables.
3416+ unsigned Iter = allocateLocalPrimitive (
3417+ Stripped, SizeT, /* IsConst=*/ false , /* IsExtended=*/ false );
3418+ if (!this ->emitConst (StaticInitElems, SizeT, E))
3419+ return false ;
3420+ if (!this ->emitSetLocal (SizeT, Iter, E))
3421+ return false ;
3422+
3423+ this ->fallthrough (StartLabel);
3424+ this ->emitLabel (StartLabel);
3425+ // Condition. Iter < ArrayLen?
3426+ if (!this ->emitGetLocal (SizeT, Iter, E))
3427+ return false ;
3428+ if (!this ->emitGetLocal (SizeT, ArrayLen, E))
3429+ return false ;
3430+ if (!this ->emitLT (SizeT, E))
3431+ return false ;
3432+ if (!this ->jumpFalse (EndLabel))
3433+ return false ;
3434+
3435+ // Pointer to the allocated array is already on the stack.
3436+ if (!this ->emitGetLocal (SizeT, Iter, E))
3437+ return false ;
3438+ if (!this ->emitArrayElemPtr (SizeT, E))
3439+ return false ;
3440+
3441+ if (DynamicInit) {
3442+ if (std::optional<PrimType> InitT = classify (DynamicInit)) {
3443+ if (!this ->visit (DynamicInit))
3444+ return false ;
3445+ if (!this ->emitStorePop (*InitT, E))
3446+ return false ;
3447+ } else {
3448+ if (!this ->visitInitializer (DynamicInit))
3449+ return false ;
3450+ if (!this ->emitPopPtr (E))
3451+ return false ;
3452+ }
3453+ } else {
3454+ assert (CtorFunc);
3455+ if (!this ->emitCall (CtorFunc, 0 , E))
3456+ return false ;
3457+ }
3458+
3459+ // ++Iter;
3460+ if (!this ->emitGetPtrLocal (Iter, E))
3461+ return false ;
3462+ if (!this ->emitIncPop (SizeT, E))
3463+ return false ;
3464+
3465+ if (!this ->jump (StartLabel))
3466+ return false ;
3467+
3468+ this ->fallthrough (EndLabel);
3469+ this ->emitLabel (EndLabel);
3470+ }
3471+ }
3472+ } else { // Non-array.
33993473 if (PlacementDest) {
34003474 if (!this ->visit (PlacementDest))
34013475 return false ;
0 commit comments