Skip to content

Commit f8fab21

Browse files
authored
[Clang][Sema] Fix type of enumerators in incomplete enumerations (#84068)
Enumerators dont have the type of their enumeration before the closing brace. In these cases Expr::getEnumCoercedType() incorrectly returned the enumeration type. Introduced in PR #81418 Fixes #84712
1 parent afd4758 commit f8fab21

File tree

3 files changed

+30
-6
lines changed

3 files changed

+30
-6
lines changed

clang/lib/AST/Expr.cpp

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -264,11 +264,14 @@ namespace {
264264
}
265265

266266
QualType Expr::getEnumCoercedType(const ASTContext &Ctx) const {
267-
if (isa<EnumType>(this->getType()))
268-
return this->getType();
269-
else if (const auto *ECD = this->getEnumConstantDecl())
270-
return Ctx.getTypeDeclType(cast<EnumDecl>(ECD->getDeclContext()));
271-
return this->getType();
267+
if (isa<EnumType>(getType()))
268+
return getType();
269+
if (const auto *ECD = getEnumConstantDecl()) {
270+
const auto *ED = cast<EnumDecl>(ECD->getDeclContext());
271+
if (ED->isCompleteDefinition())
272+
return Ctx.getTypeDeclType(ED);
273+
}
274+
return getType();
272275
}
273276

274277
SourceLocation Expr::getExprLoc() const {
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// RUN: %clang_cc1 -x c++ -fsyntax-only -verify %s -Wenum-compare
2+
// expected-no-diagnostics
3+
4+
enum E1 {
5+
E11 = 0
6+
};
7+
8+
enum E2 {
9+
E21 = 0,
10+
E22 = E11,
11+
E23 = E21 + E22
12+
};

clang/test/Sema/warn-compare-enum-types-mismatch.c

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,21 @@
11
// RUN: %clang_cc1 -x c -fsyntax-only -verify -Wenum-compare -Wno-unused-comparison %s
22
// RUN: %clang_cc1 -x c++ -fsyntax-only -verify -Wenum-compare -Wno-unused-comparison %s
33

4+
// In C enumerators (i.e enumeration constants) have type int (until C23). In
5+
// order to support diagnostics such as -Wenum-compare we pretend they have the
6+
// type of their enumeration.
7+
48
typedef enum EnumA {
59
A
610
} EnumA;
711

812
enum EnumB {
9-
B
13+
B,
14+
B1 = 1,
15+
// In C++ this comparison doesnt warn as enumerators dont have the type of
16+
// their enumeration before the closing brace. We mantain the same behavior
17+
// in C.
18+
B2 = A == B1
1019
};
1120

1221
enum {

0 commit comments

Comments
 (0)