llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang Author: Akira Hatanaka (ahatanak) <details> <summary>Changes</summary> 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 --- Full diff: https://github.com/llvm/llvm-project/pull/161590.diff 2 Files Affected: - (modified) clang/lib/Sema/SemaDecl.cpp (+50-45) - (modified) clang/test/SemaCXX/attr-section.cpp (+8) ``````````diff diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 0069b08f1991a..e6271745e7ac1 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -14918,52 +14918,57 @@ 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; - bool MSVCEnv = - Context.getTargetInfo().getTriple().isWindowsMSVCEnvironment(); - std::optional<QualType::NonConstantStorageReason> Reason; - if (HasConstInit && - !(Reason = var->getType().isNonConstantStorage(Context, true, false))) { - Stack = &ConstSegStack; - } else { - SectionFlags |= ASTContext::PSF_Write; - Stack = var->hasInit() && HasConstInit ? &DataSegStack : &BSSSegStack; - } - if (const SectionAttr *SA = var->getAttr<SectionAttr>()) { - if (SA->getSyntax() == AttributeCommonInfo::AS_Declspec) + [&]() { + if (GlobalStorage && var->isThisDeclarationADefinition() && + !inTemplateInstantiation()) { + PragmaStack<StringLiteral *> *Stack = nullptr; + int SectionFlags = ASTContext::PSF_Read; + bool MSVCEnv = + Context.getTargetInfo().getTriple().isWindowsMSVCEnvironment(); + std::optional<QualType::NonConstantStorageReason> Reason; + if (HasConstInit && var->getType()->isIncompleteType()) + return; + if (HasConstInit && !(Reason = var->getType().isNonConstantStorage( + Context, true, false))) { + Stack = &ConstSegStack; + } else { + SectionFlags |= ASTContext::PSF_Write; + Stack = var->hasInit() && HasConstInit ? &DataSegStack : &BSSSegStack; + } + 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) { + if (Stack != &ConstSegStack && MSVCEnv && + ConstSegStack.CurrentValue != ConstSegStack.DefaultValue && + var->getType().isConstQualified()) { + assert((!Reason || Reason != QualType::NonConstantStorageReason:: + NonConstNonReferenceType) && + "This case should've already been handled elsewhere"); + Diag(var->getLocation(), diag::warn_section_msvc_compat) + << var << ConstSegStack.CurrentValue + << (int)(!HasConstInit + ? QualType::NonConstantStorageReason::NonTrivialCtor + : *Reason); + } SectionFlags |= ASTContext::PSF_Implicit; - UnifySection(SA->getName(), SectionFlags, var); - } else if (Stack->CurrentValue) { - if (Stack != &ConstSegStack && MSVCEnv && - ConstSegStack.CurrentValue != ConstSegStack.DefaultValue && - var->getType().isConstQualified()) { - assert((!Reason || Reason != QualType::NonConstantStorageReason:: - NonConstNonReferenceType) && - "This case should've already been handled elsewhere"); - Diag(var->getLocation(), diag::warn_section_msvc_compat) - << var << ConstSegStack.CurrentValue << (int)(!HasConstInit - ? QualType::NonConstantStorageReason::NonTrivialCtor - : *Reason); - } - SectionFlags |= ASTContext::PSF_Implicit; - auto SectionName = Stack->CurrentValue->getString(); - var->addAttr(SectionAttr::CreateImplicit(Context, SectionName, - Stack->CurrentPragmaLocation, - 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)); - } + auto SectionName = Stack->CurrentValue->getString(); + var->addAttr(SectionAttr::CreateImplicit( + Context, SectionName, Stack->CurrentPragmaLocation, + 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)); + } + }(); // All the following checks are C++ only. if (!getLangOpts().CPlusPlus) { diff --git a/clang/test/SemaCXX/attr-section.cpp b/clang/test/SemaCXX/attr-section.cpp index 1c07e3dd8bba2..3ec455d860ff0 100644 --- a/clang/test/SemaCXX/attr-section.cpp +++ b/clang/test/SemaCXX/attr-section.cpp @@ -69,3 +69,11 @@ __attribute__((section("non_trivial_ctor"))) const t1 v1; // expected-note {{dec extern const t1 v2; __attribute__((section("non_trivial_ctor"))) const t1 v2{3}; // expected-error {{'v2' causes a section type conflict with 'v1'}} } // namespace non_trivial_ctor + +namespace incomplete_type { +template <class T> +struct A { + struct B; + static constexpr B b{nullptr}; +}; +} `````````` </details> https://github.com/llvm/llvm-project/pull/161590 _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
