[clang] [Sema] Don't call isNonConstantStorage on incomplete variable types (PR #161590)

via cfe-commits cfe-commits at lists.llvm.org
Wed Oct 1 14:32:58 PDT 2025


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


More information about the cfe-commits mailing list