[clang] [clang] fix obtaining underlying type for demoted enum definitions (PR #155900)

via cfe-commits cfe-commits at lists.llvm.org
Thu Aug 28 11:11:11 PDT 2025


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang

@llvm/pr-subscribers-clang-modules

Author: Matheus Izvekov (mizvekov)

<details>
<summary>Changes</summary>

Clang skips parsing a TagDecl definition in case a definition was already parsed in another module.

In those cases, an EnumDecl might be left without an IntegerType. Take this into account when getting the underlying type of an enum, look for the integer type in the definition instead in those cases.

This patch also changes the implementation so it properly marks those skipped tag definitions as demoted.

This fixes a regression reported here: https://github.com/llvm/llvm-project/pull/155028#issuecomment-3233410561

Since this regression was never released, there are no release notes.

---
Full diff: https://github.com/llvm/llvm-project/pull/155900.diff


3 Files Affected:

- (modified) clang/lib/Sema/SemaDecl.cpp (+8-2) 
- (modified) clang/lib/Sema/SemaType.cpp (+8-1) 
- (added) clang/test/Modules/GH155028-1.cpp (+17) 


``````````diff
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index a47c5ab3aaff7..73f92f7ec9a1e 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -18544,8 +18544,14 @@ Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK, SourceLocation KWLoc,
   if (PrevDecl)
     CheckRedeclarationInModule(New, PrevDecl);
 
-  if (TUK == TagUseKind::Definition && (!SkipBody || !SkipBody->ShouldSkip))
-    New->startDefinition();
+  if (TUK == TagUseKind::Definition) {
+    if (!SkipBody || !SkipBody->ShouldSkip) {
+      New->startDefinition();
+    } else {
+      New->setCompleteDefinition();
+      New->demoteThisDefinitionToDeclaration();
+    }
+  }
 
   ProcessDeclAttributeList(S, New, Attrs);
   AddPragmaAttributes(S, New);
diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp
index 3f31a05d382a6..0f655d7f684a5 100644
--- a/clang/lib/Sema/SemaType.cpp
+++ b/clang/lib/Sema/SemaType.cpp
@@ -9878,7 +9878,14 @@ static QualType GetEnumUnderlyingType(Sema &S, QualType BaseType,
   S.DiagnoseUseOfDecl(ED, Loc);
 
   QualType Underlying = ED->getIntegerType();
-  assert(!Underlying.isNull());
+  if (Underlying.isNull()) {
+    // This is an enum without a fixed underlying type which we skipped parsing
+    // the body because we saw its definition previously in another module.
+    // Use the definition's integer type in that case.
+    assert(ED->isThisDeclarationADemotedDefinition());
+    Underlying = ED->getDefinition()->getIntegerType();
+    assert(!Underlying.isNull());
+  }
 
   return Underlying;
 }
diff --git a/clang/test/Modules/GH155028-1.cpp b/clang/test/Modules/GH155028-1.cpp
new file mode 100644
index 0000000000000..d60112b48c218
--- /dev/null
+++ b/clang/test/Modules/GH155028-1.cpp
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 -std=c++20 -verify %s
+// expected-no-diagnostics
+
+#pragma clang module build M
+module "M" {
+  module "A" {}
+  module "B" {}
+}
+#pragma clang module contents
+#pragma clang module begin M.A
+enum E1 {};
+#pragma clang module end
+#pragma clang module begin M.B
+enum E1 {};
+using T = __underlying_type(E1);
+#pragma clang module end
+#pragma clang module endbuild

``````````

</details>


https://github.com/llvm/llvm-project/pull/155900


More information about the cfe-commits mailing list