Emit const globals with constexpr destructor as constant LLVM values
This follows 2b4fa53 which made Clang not emit destructor calls for such
objects. However, they would still not get emitted as constants since
CodeGenModule::isTypeConstant() returns false if the destructor is
constexpr. This change adds a param to make isTypeConstant() ignore the
dtor, allowing the caller to check it instead.
Fixes Issue #61212
Differential revision: https://reviews.llvm.org/D145369
This commit is contained in:
@@ -3130,7 +3130,7 @@ bool CodeGenModule::MayBeEmittedEagerly(const ValueDecl *Global) {
|
||||
// codegen for global variables, because they may be marked as threadprivate.
|
||||
if (LangOpts.OpenMP && LangOpts.OpenMPUseTLS &&
|
||||
getContext().getTargetInfo().isTLSSupported() && isa<VarDecl>(Global) &&
|
||||
!isTypeConstant(Global->getType(), false) &&
|
||||
!isTypeConstant(Global->getType(), false, false) &&
|
||||
!OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(Global))
|
||||
return false;
|
||||
|
||||
@@ -4335,8 +4335,9 @@ CodeGenModule::CreateRuntimeFunction(llvm::FunctionType *FTy, StringRef Name,
|
||||
///
|
||||
/// If ExcludeCtor is true, the duration when the object's constructor runs
|
||||
/// will not be considered. The caller will need to verify that the object is
|
||||
/// not written to during its construction.
|
||||
bool CodeGenModule::isTypeConstant(QualType Ty, bool ExcludeCtor) {
|
||||
/// not written to during its construction. ExcludeDtor works similarly.
|
||||
bool CodeGenModule::isTypeConstant(QualType Ty, bool ExcludeCtor,
|
||||
bool ExcludeDtor) {
|
||||
if (!Ty.isConstant(Context) && !Ty->isReferenceType())
|
||||
return false;
|
||||
|
||||
@@ -4344,7 +4345,7 @@ bool CodeGenModule::isTypeConstant(QualType Ty, bool ExcludeCtor) {
|
||||
if (const CXXRecordDecl *Record
|
||||
= Context.getBaseElementType(Ty)->getAsCXXRecordDecl())
|
||||
return ExcludeCtor && !Record->hasMutableFields() &&
|
||||
Record->hasTrivialDestructor();
|
||||
(Record->hasTrivialDestructor() || ExcludeDtor);
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -4457,7 +4458,7 @@ CodeGenModule::GetOrCreateLLVMGlobal(StringRef MangledName, llvm::Type *Ty,
|
||||
|
||||
// FIXME: This code is overly simple and should be merged with other global
|
||||
// handling.
|
||||
GV->setConstant(isTypeConstant(D->getType(), false));
|
||||
GV->setConstant(isTypeConstant(D->getType(), false, false));
|
||||
|
||||
GV->setAlignment(getContext().getDeclAlign(D).getAsAlign());
|
||||
|
||||
@@ -5013,7 +5014,7 @@ void CodeGenModule::EmitGlobalVarDefinition(const VarDecl *D,
|
||||
|
||||
// If it is safe to mark the global 'constant', do so now.
|
||||
GV->setConstant(!NeedsGlobalCtor && !NeedsGlobalDtor &&
|
||||
isTypeConstant(D->getType(), true));
|
||||
isTypeConstant(D->getType(), true, true));
|
||||
|
||||
// If it is in a read-only section, mark it 'constant'.
|
||||
if (const SectionAttr *SA = D->getAttr<SectionAttr>()) {
|
||||
@@ -6087,7 +6088,8 @@ ConstantAddress CodeGenModule::GetAddrOfGlobalTemporary(
|
||||
emitter.emplace(*this);
|
||||
InitialValue = emitter->emitForInitializer(*Value, AddrSpace,
|
||||
MaterializedType);
|
||||
Constant = isTypeConstant(MaterializedType, /*ExcludeCtor*/Value);
|
||||
Constant = isTypeConstant(MaterializedType, /*ExcludeCtor*/ Value,
|
||||
/*ExcludeDtor*/ false);
|
||||
Type = InitialValue->getType();
|
||||
} else {
|
||||
// No initializer, the initialization will be provided when we
|
||||
|
||||
Reference in New Issue
Block a user