Skip to content

Commit

Permalink
Emit vector deleting dtor even if scalar dtor was emitted already
Browse files Browse the repository at this point in the history
Sometimes new[] expression ends up in a function that is itself deferred
so we first emit scalar destructor as a deferred decl then meet new[]
for the type. Need to switch to vector deleting dtor then.
  • Loading branch information
Fznamznon committed Jan 21, 2025
1 parent 4f50e81 commit c5bb3df
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 5 deletions.
4 changes: 3 additions & 1 deletion clang/lib/CodeGen/CGExprCXX.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1209,7 +1209,9 @@ void CodeGenFunction::EmitNewArrayInitializer(
EmitCXXAggrConstructorCall(Ctor, NumElements, CurPtr, CCE,
/*NewPointerIsChecked*/true,
CCE->requiresZeroInitialization());
CGM.recordVectorDestructorRequirement(Ctor->getParent());
if (CGM.getCXXABI().hasVectorDeletingDtors()) {
CGM.requireVectorDestructorDefinition(Ctor->getParent());
}
return;
}

Expand Down
25 changes: 25 additions & 0 deletions clang/lib/CodeGen/CodeGenModule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7910,3 +7910,28 @@ void CodeGenModule::moveLazyEmissionStates(CodeGenModule *NewBuilder) {

NewBuilder->ABI->MangleCtx = std::move(ABI->MangleCtx);
}

void CodeGenModule::requireVectorDestructorDefinition(const CXXRecordDecl *RD) {
// FIXME check MSVC/abi supports vector destructors?
RequireVectorDeletingDtor.insert(RD);
CXXDestructorDecl *DtorD = RD->getDestructor();
GlobalDecl ScalarDtorGD(DtorD, Dtor_Deleting);
StringRef MangledName = getMangledName(ScalarDtorGD);
llvm::GlobalValue *Entry = GetGlobalValue(MangledName);
if (Entry && !Entry->isDeclaration()) {
GlobalDecl VectorDtorGD(DtorD, Dtor_VectorDeleting);
StringRef VDName = getMangledName(VectorDtorGD);
llvm::GlobalValue *VDEntry = GetGlobalValue(VDName);
// It exists and it should be an alias.
assert(VDEntry);
auto *NewFn = llvm::Function::Create(
cast<llvm::FunctionType>(VDEntry->getValueType()),
llvm::Function::ExternalLinkage, VDName, &getModule());
NewFn->takeName(VDEntry);
VDEntry->replaceAllUsesWith(NewFn);
VDEntry->eraseFromParent();
Entry->replaceAllUsesWith(NewFn);
Entry->eraseFromParent();
addDeferredDeclToEmit(VectorDtorGD);
}
}
5 changes: 1 addition & 4 deletions clang/lib/CodeGen/CodeGenModule.h
Original file line number Diff line number Diff line change
Expand Up @@ -1793,10 +1793,7 @@ class CodeGenModule : public CodeGenTypeCache {
// behavior. So projects like the Linux kernel can rely on it.
return !getLangOpts().CPlusPlus;
}
void recordVectorDestructorRequirement(const CXXRecordDecl *RD) {
// FIXME check MSVC/abi supports vector destructors?
RequireVectorDeletingDtor.insert(RD);
}
void requireVectorDestructorDefinition(const CXXRecordDecl *RD);
bool classNeedsVectorDestructor(const CXXRecordDecl *RD) {
// FIXME check MSVC/abi supports vector destructors?
return RequireVectorDeletingDtor.count(RD);
Expand Down

0 comments on commit c5bb3df

Please sign in to comment.