diff options
| author | Timm Baeder <tbaeder@redhat.com> | 2025-06-30 16:59:57 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-06-30 16:59:57 +0200 |
| commit | 00cdaa5c395c122f8ede2a4b0587bf9a0dfecc2a (patch) | |
| tree | 53681e3d133c3951d31888f03ebed4a8e53fb041 /clang | |
| parent | 53102a395f3bd07762c183c9ecd213a4759559dd (diff) | |
[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.
Diffstat (limited to 'clang')
| -rw-r--r-- | clang/lib/AST/ByteCode/Compiler.h | 18 | ||||
| -rw-r--r-- | clang/lib/AST/ByteCode/Descriptor.cpp | 15 | ||||
| -rw-r--r-- | clang/lib/AST/ByteCode/Descriptor.h | 3 |
3 files changed, 27 insertions, 9 deletions
diff --git a/clang/lib/AST/ByteCode/Compiler.h b/clang/lib/AST/ByteCode/Compiler.h index a1d068cc7e0a..1a5fd8678587 100644 --- a/clang/lib/AST/ByteCode/Compiler.h +++ b/clang/lib/AST/ByteCode/Compiler.h @@ -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; } diff --git a/clang/lib/AST/ByteCode/Descriptor.cpp b/clang/lib/AST/ByteCode/Descriptor.cpp index 46e4d0d940b3..c89eca9bef44 100644 --- a/clang/lib/AST/ByteCode/Descriptor.cpp +++ b/clang/lib/AST/ByteCode/Descriptor.cpp @@ -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) diff --git a/clang/lib/AST/ByteCode/Descriptor.h b/clang/lib/AST/ByteCode/Descriptor.h index f25ad8f4c758..4591eabb69bb 100644 --- a/clang/lib/AST/ByteCode/Descriptor.h +++ b/clang/lib/AST/ByteCode/Descriptor.h @@ -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; |
