Skip to content

Commit 3da4729

Browse files
authored
[clang] fix obtaining underlying type for demoted enum definitions (#155900)
1 parent 2859165 commit 3da4729

File tree

3 files changed

+33
-3
lines changed

3 files changed

+33
-3
lines changed

clang/lib/Sema/SemaDecl.cpp

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18544,8 +18544,14 @@ Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK, SourceLocation KWLoc,
1854418544
if (PrevDecl)
1854518545
CheckRedeclarationInModule(New, PrevDecl);
1854618546

18547-
if (TUK == TagUseKind::Definition && (!SkipBody || !SkipBody->ShouldSkip))
18548-
New->startDefinition();
18547+
if (TUK == TagUseKind::Definition) {
18548+
if (!SkipBody || !SkipBody->ShouldSkip) {
18549+
New->startDefinition();
18550+
} else {
18551+
New->setCompleteDefinition();
18552+
New->demoteThisDefinitionToDeclaration();
18553+
}
18554+
}
1854918555

1855018556
ProcessDeclAttributeList(S, New, Attrs);
1855118557
AddPragmaAttributes(S, New);

clang/lib/Sema/SemaType.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9878,7 +9878,14 @@ static QualType GetEnumUnderlyingType(Sema &S, QualType BaseType,
98789878
S.DiagnoseUseOfDecl(ED, Loc);
98799879

98809880
QualType Underlying = ED->getIntegerType();
9881-
assert(!Underlying.isNull());
9881+
if (Underlying.isNull()) {
9882+
// This is an enum without a fixed underlying type which we skipped parsing
9883+
// the body because we saw its definition previously in another module.
9884+
// Use the definition's integer type in that case.
9885+
assert(ED->isThisDeclarationADemotedDefinition());
9886+
Underlying = ED->getDefinition()->getIntegerType();
9887+
assert(!Underlying.isNull());
9888+
}
98829889

98839890
return Underlying;
98849891
}

clang/test/Modules/GH155028-1.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// RUN: %clang_cc1 -std=c++20 -verify %s
2+
// expected-no-diagnostics
3+
4+
#pragma clang module build M
5+
module "M" {
6+
module "A" {}
7+
module "B" {}
8+
}
9+
#pragma clang module contents
10+
#pragma clang module begin M.A
11+
enum E1 {};
12+
#pragma clang module end
13+
#pragma clang module begin M.B
14+
enum E1 {};
15+
using T = __underlying_type(E1);
16+
#pragma clang module end
17+
#pragma clang module endbuild

0 commit comments

Comments
 (0)