@@ -246,6 +246,25 @@ static void dtorRecord(Block *B, std::byte *Ptr, const Descriptor *D) {
246246 destroyBase (B, Ptr, F.Desc , F.Offset );
247247}
248248
249+ // / Whether a record needs its descriptor dtor function called.
250+ static bool needsRecordDtor (const Record *R) {
251+ for (const auto &B : R->bases ()) {
252+ if (B.Desc ->DtorFn )
253+ return true ;
254+ }
255+
256+ for (const auto &F : R->fields ()) {
257+ if (F.Desc ->DtorFn )
258+ return true ;
259+ }
260+
261+ for (const auto &V : R->virtual_bases ()) {
262+ if (V.Desc ->DtorFn )
263+ return true ;
264+ }
265+ return false ;
266+ }
267+
249268static BlockCtorFn getCtorPrim (PrimType Type) {
250269 // Floating types are special. They are primitives, but need their
251270 // constructor called.
@@ -336,7 +355,7 @@ Descriptor::Descriptor(const DeclTy &D, const Type *SourceTy,
336355 AllocSize(std::max<size_t >(alignof (void *), Size) + MDSize),
337356 ElemDesc(Elem), IsConst(IsConst), IsMutable(IsMutable),
338357 IsTemporary(IsTemporary), IsArray(true ), CtorFn(ctorArrayDesc),
339- DtorFn(dtorArrayDesc) {
358+ DtorFn(Elem->DtorFn ? dtorArrayDesc : nullptr ) {
340359 assert (Source && " Missing source" );
341360}
342361
@@ -347,7 +366,7 @@ Descriptor::Descriptor(const DeclTy &D, const Descriptor *Elem, MetadataSize MD,
347366 Size(UnknownSizeMark), MDSize(MD.value_or(0 )),
348367 AllocSize(MDSize + alignof (void *)), ElemDesc(Elem), IsConst(true ),
349368 IsMutable(false ), IsTemporary(IsTemporary), IsArray(true ),
350- CtorFn(ctorArrayDesc), DtorFn(dtorArrayDesc) {
369+ CtorFn(ctorArrayDesc), DtorFn(Elem->DtorFn ? dtorArrayDesc : nullptr ) {
351370 assert (Source && " Missing source" );
352371}
353372
@@ -359,7 +378,7 @@ Descriptor::Descriptor(const DeclTy &D, const Record *R, MetadataSize MD,
359378 Size(ElemSize), MDSize(MD.value_or(0 )), AllocSize(Size + MDSize),
360379 ElemRecord(R), IsConst(IsConst), IsMutable(IsMutable),
361380 IsTemporary(IsTemporary), IsVolatile(IsVolatile), CtorFn(ctorRecord),
362- DtorFn(dtorRecord) {
381+ DtorFn(needsRecordDtor(R) ? dtorRecord : nullptr ) {
363382 assert (Source && " Missing source" );
364383}
365384
0 commit comments