[clang][bytecode] Add Descriptor::hasTrivialDtor() (#146286)

We sometimes used to have a long list of 

```
  GetLocalPtr
  PopPtr
  [...]
```

ops at the end of scopes, because we first got a pointer to a local
variable and only then did we figure out that we didn't actually want to
call the destructor for it. Add a new function that allows us to just
ask the `Descriptor` whether we need to call its destructor.
This commit is contained in:
Timm Baeder 2025-06-30 16:59:57 +02:00 committed by GitHub
parent 53102a395f
commit 00cdaa5c39
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 27 additions and 9 deletions

View File

@ -574,17 +574,17 @@ public:
// Emit destructor calls for local variables of record
// type with a destructor.
for (Scope::Local &Local : llvm::reverse(this->Ctx->Descriptors[*Idx])) {
if (!Local.Desc->isPrimitive() && !Local.Desc->isPrimitiveArray()) {
if (!this->Ctx->emitGetPtrLocal(Local.Offset, E))
return false;
if (Local.Desc->hasTrivialDtor())
continue;
if (!this->Ctx->emitGetPtrLocal(Local.Offset, E))
return false;
if (!this->Ctx->emitDestruction(Local.Desc, Local.Desc->getLoc()))
return false;
if (!this->Ctx->emitDestruction(Local.Desc, Local.Desc->getLoc()))
return false;
if (!this->Ctx->emitPopPtr(E))
return false;
removeIfStoredOpaqueValue(Local);
}
if (!this->Ctx->emitPopPtr(E))
return false;
removeIfStoredOpaqueValue(Local);
}
return true;
}

View File

@ -502,6 +502,21 @@ SourceInfo Descriptor::getLoc() const {
llvm_unreachable("Invalid descriptor type");
}
bool Descriptor::hasTrivialDtor() const {
if (isPrimitive() || isPrimitiveArray() || isDummy())
return true;
if (isRecord()) {
assert(ElemRecord);
const CXXDestructorDecl *Dtor = ElemRecord->getDestructor();
return !Dtor || Dtor->isTrivial();
}
// Composite arrays.
assert(ElemDesc);
return ElemDesc->hasTrivialDtor();
}
bool Descriptor::isUnion() const { return isRecord() && ElemRecord->isUnion(); }
InitMap::InitMap(unsigned N)

View File

@ -281,6 +281,9 @@ public:
/// Checks if this is a dummy descriptor.
bool isDummy() const { return IsDummy; }
/// Whether variables of this descriptor need their destructor called or not.
bool hasTrivialDtor() const;
void dump() const;
void dump(llvm::raw_ostream &OS) const;
void dumpFull(unsigned Offset = 0, unsigned Indent = 0) const;