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
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to