@@ -262,7 +262,7 @@ void SILGenFunction::emitDeallocatingMoveOnlyDestructor(DestructorDecl *dd) {
262262 // Clean up our members, consuming our +1 self value as we do it.
263263 emitMoveOnlyMemberDestruction (selfValue,
264264 dd->getDeclContext ()->getSelfNominalTypeDecl (),
265- cleanupLoc, nullptr );
265+ cleanupLoc);
266266
267267 // Return.
268268 B.createReturn (loc, emitEmptyTuple (loc));
@@ -497,111 +497,59 @@ void SILGenFunction::emitClassMemberDestruction(ManagedValue selfValue,
497497
498498void SILGenFunction::emitMoveOnlyMemberDestruction (SILValue selfValue,
499499 NominalTypeDecl *nom,
500- CleanupLocation cleanupLoc,
501- SILBasicBlock *finishBB) {
500+ CleanupLocation cleanupLoc) {
501+ // drop_deinit invalidates any user-defined struct/enum deinit
502+ // before the individual members are destroyed.
502503 selfValue = B.createDropDeinit (cleanupLoc, selfValue);
503- if (selfValue->getType ().isAddress ()) {
504- if (auto *structDecl = dyn_cast<StructDecl>(nom)) {
505- for (VarDecl *vd : nom->getStoredProperties ()) {
506- const TypeLowering &ti = getTypeLowering (vd->getType ());
507- if (ti.isTrivial ())
508- continue ;
509-
510- SILValue addr = B.createStructElementAddr (
511- cleanupLoc, selfValue, vd, ti.getLoweredType ().getAddressType ());
512- addr = B.createBeginAccess (cleanupLoc, addr, SILAccessKind::Deinit,
513- SILAccessEnforcement::Static,
514- false /* noNestedConflict*/ ,
515- false /* fromBuiltin*/ );
516- B.createDestroyAddr (cleanupLoc, addr);
517- B.createEndAccess (cleanupLoc, addr, false /* is aborting*/ );
518- }
519- } else {
520- auto *origBlock = B.getInsertionBB ();
521- auto *enumDecl = cast<EnumDecl>(nom);
522- SmallVector<std::pair<EnumElementDecl *, SILBasicBlock *>, 8 >
523- caseCleanups;
524- auto *contBlock = createBasicBlock ();
525-
526- for (auto *enumElt : enumDecl->getAllElements ()) {
527- auto *enumBlock = createBasicBlock ();
528- SILBuilder builder (enumBlock, enumBlock->begin ());
529-
530- if (enumElt->hasAssociatedValues ()) {
531- auto *take = builder.createUncheckedTakeEnumDataAddr (
532- cleanupLoc, selfValue, enumElt);
533- builder.createDestroyAddr (cleanupLoc, take);
534- }
535-
536- // Branch to the continue trampoline block.
537- builder.createBranch (cleanupLoc, contBlock);
538- caseCleanups.emplace_back (enumElt, enumBlock);
539-
540- // Set the insertion point to after this enum block so we insert the
541- // next new block after this block.
542- B.setInsertionPoint (enumBlock);
543- }
504+ if (selfValue->getType ().isObject ()) {
505+ // A destroy value that uses the result of a drop_deinit implicitly performs
506+ // memberwise destruction.
507+ B.emitDestroyValueOperation (cleanupLoc, selfValue);
508+ return ;
509+ }
510+ if (auto *structDecl = dyn_cast<StructDecl>(nom)) {
511+ for (VarDecl *vd : nom->getStoredProperties ()) {
512+ const TypeLowering &ti = getTypeLowering (vd->getType ());
513+ if (ti.isTrivial ())
514+ continue ;
544515
545- B.setInsertionPoint (origBlock);
546- B.createSwitchEnumAddr (cleanupLoc, selfValue, nullptr , caseCleanups);
547- B.setInsertionPoint (contBlock);
516+ SILValue addr = B.createStructElementAddr (
517+ cleanupLoc, selfValue, vd, ti.getLoweredType ().getAddressType ());
518+ addr = B.createBeginAccess (
519+ cleanupLoc, addr, SILAccessKind::Deinit, SILAccessEnforcement::Static,
520+ false /* noNestedConflict*/ , false /* fromBuiltin*/ );
521+ B.createDestroyAddr (cleanupLoc, addr);
522+ B.createEndAccess (cleanupLoc, addr, false /* is aborting*/ );
548523 }
549524 } else {
550- if (auto *sd = dyn_cast<StructDecl>(nom)) {
551- if (llvm::any_of (sd->getStoredProperties (),
552- [&](VarDecl *vd) {
553- auto &lowering = getTypeLowering (vd->getType ());
554- return !lowering.isTrivial ();
555- })) {
556- auto *d = B.createDestructureStruct (cleanupLoc, selfValue,
557- OwnershipKind::Owned);
558- for (auto result : d->getResults ()) {
559- B.emitDestroyValueOperation (cleanupLoc, result);
560- }
561- } else {
562- // If we only contain trivial uses, we don't have anything to cleanup,
563- // so just insert an end_lifetime.
564- B.createEndLifetime (cleanupLoc, selfValue);
525+ auto *origBlock = B.getInsertionBB ();
526+ auto *enumDecl = cast<EnumDecl>(nom);
527+ SmallVector<std::pair<EnumElementDecl *, SILBasicBlock *>, 8 > caseCleanups;
528+ auto *contBlock = createBasicBlock ();
529+
530+ for (auto *enumElt : enumDecl->getAllElements ()) {
531+ auto *enumBlock = createBasicBlock ();
532+ SILBuilder builder (enumBlock, enumBlock->begin ());
533+
534+ if (enumElt->hasAssociatedValues ()) {
535+ auto *take = builder.createUncheckedTakeEnumDataAddr (
536+ cleanupLoc, selfValue, enumElt);
537+ builder.createDestroyAddr (cleanupLoc, take);
565538 }
566- } else {
567- auto *origBlock = B.getInsertionBB ();
568- auto *enumDecl = dyn_cast<EnumDecl>(nom);
569- SmallVector<std::pair<EnumElementDecl *, SILBasicBlock *>, 8 >
570- caseCleanups;
571- auto *contBlock = createBasicBlock ();
572-
573- for (auto *enumElt : enumDecl->getAllElements ()) {
574- auto *enumBlock = createBasicBlock ();
575- SILBuilder builder (enumBlock, enumBlock->begin ());
576-
577- if (enumElt->hasAssociatedValues ()) {
578- auto caseType = selfValue->getType ().getEnumElementType (
579- enumElt, enumBlock->getParent ());
580- auto *phiArg =
581- enumBlock->createPhiArgument (caseType, OwnershipKind::Owned);
582- builder.emitDestroyValueOperation (cleanupLoc, phiArg);
583- }
584539
585- // Branch to the continue trampoline block.
586- builder.createBranch (cleanupLoc, contBlock);
587- caseCleanups.emplace_back (enumElt, enumBlock);
540+ // Branch to the continue trampoline block.
541+ builder.createBranch (cleanupLoc, contBlock);
542+ caseCleanups.emplace_back (enumElt, enumBlock);
588543
589- // Set the insertion point to after this enum block so we insert the
590- // next new block after this block.
591- B.setInsertionPoint (enumBlock);
592- }
593-
594- B.setInsertionPoint (origBlock);
595- B.createSwitchEnum (cleanupLoc, selfValue, nullptr , caseCleanups);
596- B.setInsertionPoint (contBlock);
544+ // Set the insertion point to after this enum block so we insert the
545+ // next new block after this block.
546+ B.setInsertionPoint (enumBlock);
597547 }
598- }
599548
600- if (finishBB)
601- B.createBranch (cleanupLoc, finishBB);
602-
603- if (finishBB)
604- B.emitBlock (finishBB);
549+ B.setInsertionPoint (origBlock);
550+ B.createSwitchEnumAddr (cleanupLoc, selfValue, nullptr , caseCleanups);
551+ B.setInsertionPoint (contBlock);
552+ }
605553}
606554
607555void SILGenFunction::emitObjCDestructor (SILDeclRef dtor) {
0 commit comments