Skip to content

Commit 2826b3a

Browse files
committed
[clang] fix obtaining underlying type for demoted enum definitions
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: #155028 (comment) Since this regression was never released, there are no release notes.
1 parent 3b963f9 commit 2826b3a

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)