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