forked from OSchip/llvm-project
Revert "Do not create LLVM IR `constant`s for objects with dynamic initialisation"
This reverts commit 13dd65b3a1
.
Breaks check-clang on macOS, see https://reviews.llvm.org/D102693
This commit is contained in:
parent
a0169b2ed1
commit
d881319cc5
|
@ -13047,6 +13047,43 @@ void Sema::CheckCompleteVariableDeclaration(VarDecl *var) {
|
|||
}
|
||||
}
|
||||
|
||||
// Apply section attributes and pragmas to global variables.
|
||||
bool GlobalStorage = var->hasGlobalStorage();
|
||||
if (GlobalStorage && var->isThisDeclarationADefinition() &&
|
||||
!inTemplateInstantiation()) {
|
||||
PragmaStack<StringLiteral *> *Stack = nullptr;
|
||||
int SectionFlags = ASTContext::PSF_Read;
|
||||
if (var->getType().isConstQualified())
|
||||
Stack = &ConstSegStack;
|
||||
else if (!var->getInit()) {
|
||||
Stack = &BSSSegStack;
|
||||
SectionFlags |= ASTContext::PSF_Write;
|
||||
} else {
|
||||
Stack = &DataSegStack;
|
||||
SectionFlags |= ASTContext::PSF_Write;
|
||||
}
|
||||
if (const SectionAttr *SA = var->getAttr<SectionAttr>()) {
|
||||
if (SA->getSyntax() == AttributeCommonInfo::AS_Declspec)
|
||||
SectionFlags |= ASTContext::PSF_Implicit;
|
||||
UnifySection(SA->getName(), SectionFlags, var);
|
||||
} else if (Stack->CurrentValue) {
|
||||
SectionFlags |= ASTContext::PSF_Implicit;
|
||||
auto SectionName = Stack->CurrentValue->getString();
|
||||
var->addAttr(SectionAttr::CreateImplicit(
|
||||
Context, SectionName, Stack->CurrentPragmaLocation,
|
||||
AttributeCommonInfo::AS_Pragma, SectionAttr::Declspec_allocate));
|
||||
if (UnifySection(SectionName, SectionFlags, var))
|
||||
var->dropAttr<SectionAttr>();
|
||||
}
|
||||
|
||||
// Apply the init_seg attribute if this has an initializer. If the
|
||||
// initializer turns out to not be dynamic, we'll end up ignoring this
|
||||
// attribute.
|
||||
if (CurInitSeg && var->getInit())
|
||||
var->addAttr(InitSegAttr::CreateImplicit(Context, CurInitSeg->getString(),
|
||||
CurInitSegLoc,
|
||||
AttributeCommonInfo::AS_Pragma));
|
||||
}
|
||||
|
||||
if (!var->getType()->isStructureType() && var->hasInit() &&
|
||||
isa<InitListExpr>(var->getInit())) {
|
||||
|
@ -13096,6 +13133,14 @@ void Sema::CheckCompleteVariableDeclaration(VarDecl *var) {
|
|||
}
|
||||
}
|
||||
|
||||
// All the following checks are C++ only.
|
||||
if (!getLangOpts().CPlusPlus) {
|
||||
// If this variable must be emitted, add it as an initializer for the
|
||||
// current module.
|
||||
if (Context.DeclMustBeEmitted(var) && !ModuleScopes.empty())
|
||||
Context.addModuleInitializer(ModuleScopes.back().Module, var);
|
||||
return;
|
||||
}
|
||||
|
||||
QualType type = var->getType();
|
||||
|
||||
|
@ -13103,14 +13148,11 @@ void Sema::CheckCompleteVariableDeclaration(VarDecl *var) {
|
|||
getCurFunction()->addByrefBlockVar(var);
|
||||
|
||||
Expr *Init = var->getInit();
|
||||
bool GlobalStorage = var->hasGlobalStorage();
|
||||
bool IsGlobal = GlobalStorage && !var->isStaticLocal();
|
||||
QualType baseType = Context.getBaseElementType(type);
|
||||
bool HasConstInit = true;
|
||||
|
||||
// Check whether the initializer is sufficiently constant.
|
||||
if (getLangOpts().CPlusPlus && !type->isDependentType() && Init &&
|
||||
!Init->isValueDependent() &&
|
||||
if (!type->isDependentType() && Init && !Init->isValueDependent() &&
|
||||
(GlobalStorage || var->isConstexpr() ||
|
||||
var->mightBeUsableInConstantExpressions(Context))) {
|
||||
// If this variable might have a constant initializer or might be usable in
|
||||
|
@ -13118,6 +13160,7 @@ void Sema::CheckCompleteVariableDeclaration(VarDecl *var) {
|
|||
// do this lazily, because the result might depend on things that change
|
||||
// later, such as which constexpr functions happen to be defined.
|
||||
SmallVector<PartialDiagnosticAt, 8> Notes;
|
||||
bool HasConstInit;
|
||||
if (!getLangOpts().CPlusPlus11) {
|
||||
// Prior to C++11, in contexts where a constant initializer is required,
|
||||
// the set of valid constant initializers is described by syntactic rules
|
||||
|
@ -13182,57 +13225,6 @@ void Sema::CheckCompleteVariableDeclaration(VarDecl *var) {
|
|||
}
|
||||
}
|
||||
|
||||
// Apply section attributes and pragmas to global variables.
|
||||
if (GlobalStorage && var->isThisDeclarationADefinition() &&
|
||||
!inTemplateInstantiation()) {
|
||||
PragmaStack<StringLiteral *> *Stack = nullptr;
|
||||
int SectionFlags = ASTContext::PSF_Read;
|
||||
if (var->getType().isConstQualified()) {
|
||||
if (HasConstInit)
|
||||
Stack = &ConstSegStack;
|
||||
else {
|
||||
Stack = &BSSSegStack;
|
||||
SectionFlags |= ASTContext::PSF_Write;
|
||||
}
|
||||
} else if (var->hasInit() && HasConstInit) {
|
||||
Stack = &DataSegStack;
|
||||
SectionFlags |= ASTContext::PSF_Write;
|
||||
} else {
|
||||
Stack = &BSSSegStack;
|
||||
SectionFlags |= ASTContext::PSF_Write;
|
||||
}
|
||||
if (const SectionAttr *SA = var->getAttr<SectionAttr>()) {
|
||||
if (SA->getSyntax() == AttributeCommonInfo::AS_Declspec)
|
||||
SectionFlags |= ASTContext::PSF_Implicit;
|
||||
UnifySection(SA->getName(), SectionFlags, var);
|
||||
} else if (Stack->CurrentValue) {
|
||||
SectionFlags |= ASTContext::PSF_Implicit;
|
||||
auto SectionName = Stack->CurrentValue->getString();
|
||||
var->addAttr(SectionAttr::CreateImplicit(
|
||||
Context, SectionName, Stack->CurrentPragmaLocation,
|
||||
AttributeCommonInfo::AS_Pragma, SectionAttr::Declspec_allocate));
|
||||
if (UnifySection(SectionName, SectionFlags, var))
|
||||
var->dropAttr<SectionAttr>();
|
||||
}
|
||||
|
||||
// Apply the init_seg attribute if this has an initializer. If the
|
||||
// initializer turns out to not be dynamic, we'll end up ignoring this
|
||||
// attribute.
|
||||
if (CurInitSeg && var->getInit())
|
||||
var->addAttr(InitSegAttr::CreateImplicit(Context, CurInitSeg->getString(),
|
||||
CurInitSegLoc,
|
||||
AttributeCommonInfo::AS_Pragma));
|
||||
}
|
||||
|
||||
// All the following checks are C++ only.
|
||||
if (!getLangOpts().CPlusPlus) {
|
||||
// If this variable must be emitted, add it as an initializer for the
|
||||
// current module.
|
||||
if (Context.DeclMustBeEmitted(var) && !ModuleScopes.empty())
|
||||
Context.addModuleInitializer(ModuleScopes.back().Module, var);
|
||||
return;
|
||||
}
|
||||
|
||||
// Require the destructor.
|
||||
if (!type->isDependentType())
|
||||
if (const RecordType *recordType = baseType->getAs<RecordType>())
|
||||
|
|
|
@ -1,50 +0,0 @@
|
|||
// RUN: %clang_cc1 -triple x86_64-linux -emit-llvm -o - %s | FileCheck %s --check-prefix=LLVM
|
||||
// RUN: %clang_cc1 -triple x86_64-linux -S -o - %s | FileCheck %s --check-prefix=ASM
|
||||
// Actually, any ELF target would do
|
||||
// REQUIRES: x86_64-linux
|
||||
|
||||
#pragma clang section bss = "B$$" data = "d@t@" rodata = "r0d@t@"
|
||||
|
||||
const int a = 1;
|
||||
const int *f() { return &a; }
|
||||
|
||||
int init();
|
||||
const int b = init();
|
||||
|
||||
int c = 2;
|
||||
|
||||
int d = init();
|
||||
|
||||
int e;
|
||||
|
||||
// LLVM: @_ZL1a = internal constant i32 1, align 4 #[[#A:]]
|
||||
// LLVM: @_ZL1b = internal global i32 0, align 4 #[[#A]]
|
||||
// LLVM: @c = {{.*}}global i32 2, align 4 #[[#A]]
|
||||
// LLVM: @d = {{.*}}global i32 0, align 4 #[[#A]]
|
||||
// LLVM: @e = {{.*}}global i32 0, align 4 #[[#A]]
|
||||
|
||||
// LLVM: attributes #[[#A]] = { "bss-section"="B$$" "data-section"="d@t@" "rodata-section"="r0d@t@" }
|
||||
|
||||
// ASM: .section "r0d@t@","a",@progbits
|
||||
// ASM-NOT: .section
|
||||
// ASM-LABEL: _ZL1a:
|
||||
// ASM-NEXT: .long 1
|
||||
|
||||
// ASM: .section "B$$","aw",@nobits
|
||||
// ASM-NOT: .section
|
||||
// ASM-LABEL: _ZL1b:
|
||||
// ASM-NEXT: .long 0
|
||||
|
||||
// ASM: .section "d@t@","aw",@progbits
|
||||
// ASM-NOT: .section
|
||||
// ASM-LABEL: c:
|
||||
// ASM: .long 2
|
||||
|
||||
// ASM: .section "B$$","aw",@nobits
|
||||
// ASM-NOT: .section
|
||||
// ASM-LABEL: d:
|
||||
// ASM: .long 0
|
||||
|
||||
// ASM-NOT: .section
|
||||
// ASM-LABEL: e:
|
||||
// ASM .long 0
|
|
@ -1,25 +0,0 @@
|
|||
// RUN: %clang_cc1 -triple %itanium_abi_triple -emit-llvm -o - %s | FileCheck %s
|
||||
|
||||
__attribute__((section("A")))
|
||||
const int a = 1;
|
||||
const int *f() { return &a; }
|
||||
// CHECK: @_ZL1a = internal constant i32 1, section "A"
|
||||
|
||||
int init();
|
||||
__attribute__((section("B")))
|
||||
const int b = init();
|
||||
// Even if it's const-qualified, it must not be LLVM IR `constant` since it's
|
||||
// dynamically initialised.
|
||||
// CHECK: @_ZL1b = internal global i32 0, section "B"
|
||||
|
||||
__attribute__((section("C")))
|
||||
int c = 2;
|
||||
// CHECK: @c = {{.*}}global i32 2, section "C"
|
||||
|
||||
__attribute__((section("D")))
|
||||
int d = init();
|
||||
// CHECK: @d = {{.*}}global i32 0, section "D"
|
||||
|
||||
__attribute__((section("E")))
|
||||
int e;
|
||||
// CHECK: @e = {{.*}}global i32 0, section "E", align 4
|
Loading…
Reference in New Issue