Skip to content

Commit a46d411

Browse files
committed
[Sema] Don't call isNonConstantStorage on incomplete variable types
The code that applies section attributes to global variables was crashing when it encountered a variable whose type was incomplete. This change adds a check to ensure the variable's type is complete before calling the function. Fixes #120371 rdar://155577913
1 parent 69a53b8 commit a46d411

File tree

2 files changed

+58
-45
lines changed

2 files changed

+58
-45
lines changed

clang/lib/Sema/SemaDecl.cpp

Lines changed: 50 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -14918,52 +14918,57 @@ void Sema::CheckCompleteVariableDeclaration(VarDecl *var) {
1491814918
}
1491914919

1492014920
// Apply section attributes and pragmas to global variables.
14921-
if (GlobalStorage && var->isThisDeclarationADefinition() &&
14922-
!inTemplateInstantiation()) {
14923-
PragmaStack<StringLiteral *> *Stack = nullptr;
14924-
int SectionFlags = ASTContext::PSF_Read;
14925-
bool MSVCEnv =
14926-
Context.getTargetInfo().getTriple().isWindowsMSVCEnvironment();
14927-
std::optional<QualType::NonConstantStorageReason> Reason;
14928-
if (HasConstInit &&
14929-
!(Reason = var->getType().isNonConstantStorage(Context, true, false))) {
14930-
Stack = &ConstSegStack;
14931-
} else {
14932-
SectionFlags |= ASTContext::PSF_Write;
14933-
Stack = var->hasInit() && HasConstInit ? &DataSegStack : &BSSSegStack;
14934-
}
14935-
if (const SectionAttr *SA = var->getAttr<SectionAttr>()) {
14936-
if (SA->getSyntax() == AttributeCommonInfo::AS_Declspec)
14921+
[&]() {
14922+
if (GlobalStorage && var->isThisDeclarationADefinition() &&
14923+
!inTemplateInstantiation()) {
14924+
PragmaStack<StringLiteral *> *Stack = nullptr;
14925+
int SectionFlags = ASTContext::PSF_Read;
14926+
bool MSVCEnv =
14927+
Context.getTargetInfo().getTriple().isWindowsMSVCEnvironment();
14928+
std::optional<QualType::NonConstantStorageReason> Reason;
14929+
if (HasConstInit && var->getType()->isIncompleteType())
14930+
return;
14931+
if (HasConstInit && !(Reason = var->getType().isNonConstantStorage(
14932+
Context, true, false))) {
14933+
Stack = &ConstSegStack;
14934+
} else {
14935+
SectionFlags |= ASTContext::PSF_Write;
14936+
Stack = var->hasInit() && HasConstInit ? &DataSegStack : &BSSSegStack;
14937+
}
14938+
if (const SectionAttr *SA = var->getAttr<SectionAttr>()) {
14939+
if (SA->getSyntax() == AttributeCommonInfo::AS_Declspec)
14940+
SectionFlags |= ASTContext::PSF_Implicit;
14941+
UnifySection(SA->getName(), SectionFlags, var);
14942+
} else if (Stack->CurrentValue) {
14943+
if (Stack != &ConstSegStack && MSVCEnv &&
14944+
ConstSegStack.CurrentValue != ConstSegStack.DefaultValue &&
14945+
var->getType().isConstQualified()) {
14946+
assert((!Reason || Reason != QualType::NonConstantStorageReason::
14947+
NonConstNonReferenceType) &&
14948+
"This case should've already been handled elsewhere");
14949+
Diag(var->getLocation(), diag::warn_section_msvc_compat)
14950+
<< var << ConstSegStack.CurrentValue
14951+
<< (int)(!HasConstInit
14952+
? QualType::NonConstantStorageReason::NonTrivialCtor
14953+
: *Reason);
14954+
}
1493714955
SectionFlags |= ASTContext::PSF_Implicit;
14938-
UnifySection(SA->getName(), SectionFlags, var);
14939-
} else if (Stack->CurrentValue) {
14940-
if (Stack != &ConstSegStack && MSVCEnv &&
14941-
ConstSegStack.CurrentValue != ConstSegStack.DefaultValue &&
14942-
var->getType().isConstQualified()) {
14943-
assert((!Reason || Reason != QualType::NonConstantStorageReason::
14944-
NonConstNonReferenceType) &&
14945-
"This case should've already been handled elsewhere");
14946-
Diag(var->getLocation(), diag::warn_section_msvc_compat)
14947-
<< var << ConstSegStack.CurrentValue << (int)(!HasConstInit
14948-
? QualType::NonConstantStorageReason::NonTrivialCtor
14949-
: *Reason);
14950-
}
14951-
SectionFlags |= ASTContext::PSF_Implicit;
14952-
auto SectionName = Stack->CurrentValue->getString();
14953-
var->addAttr(SectionAttr::CreateImplicit(Context, SectionName,
14954-
Stack->CurrentPragmaLocation,
14955-
SectionAttr::Declspec_allocate));
14956-
if (UnifySection(SectionName, SectionFlags, var))
14957-
var->dropAttr<SectionAttr>();
14958-
}
14959-
14960-
// Apply the init_seg attribute if this has an initializer. If the
14961-
// initializer turns out to not be dynamic, we'll end up ignoring this
14962-
// attribute.
14963-
if (CurInitSeg && var->getInit())
14964-
var->addAttr(InitSegAttr::CreateImplicit(Context, CurInitSeg->getString(),
14965-
CurInitSegLoc));
14966-
}
14956+
auto SectionName = Stack->CurrentValue->getString();
14957+
var->addAttr(SectionAttr::CreateImplicit(
14958+
Context, SectionName, Stack->CurrentPragmaLocation,
14959+
SectionAttr::Declspec_allocate));
14960+
if (UnifySection(SectionName, SectionFlags, var))
14961+
var->dropAttr<SectionAttr>();
14962+
}
14963+
14964+
// Apply the init_seg attribute if this has an initializer. If the
14965+
// initializer turns out to not be dynamic, we'll end up ignoring this
14966+
// attribute.
14967+
if (CurInitSeg && var->getInit())
14968+
var->addAttr(InitSegAttr::CreateImplicit(
14969+
Context, CurInitSeg->getString(), CurInitSegLoc));
14970+
}
14971+
}();
1496714972

1496814973
// All the following checks are C++ only.
1496914974
if (!getLangOpts().CPlusPlus) {

clang/test/SemaCXX/attr-section.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,3 +69,11 @@ __attribute__((section("non_trivial_ctor"))) const t1 v1; // expected-note {{dec
6969
extern const t1 v2;
7070
__attribute__((section("non_trivial_ctor"))) const t1 v2{3}; // expected-error {{'v2' causes a section type conflict with 'v1'}}
7171
} // namespace non_trivial_ctor
72+
73+
namespace incomplete_type {
74+
template <class T>
75+
struct A {
76+
struct B;
77+
static constexpr B b{nullptr};
78+
};
79+
}

0 commit comments

Comments
 (0)