https://github.com/Kupa-Martin updated https://github.com/llvm/llvm-project/pull/84068
>From 57538a2e2b9446cf692d11386b3560225eb86ce4 Mon Sep 17 00:00:00 2001 From: 44-2-Kupa-Martin <kupamartinclassr...@gmail.com> Date: Tue, 5 Mar 2024 17:21:02 -0300 Subject: [PATCH] [Clang][Sema] Fix type of enumerators in incomplete enumerations 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 --- clang/lib/AST/Expr.cpp | 13 ++++++++----- clang/test/Sema/enum-constant-type.cpp | 12 ++++++++++++ clang/test/Sema/warn-compare-enum-types-mismatch.c | 9 ++++++++- 3 files changed, 28 insertions(+), 6 deletions(-) create mode 100644 clang/test/Sema/enum-constant-type.cpp diff --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp index b4de2155adcebd..f5ad402e3bd73e 100644 --- a/clang/lib/AST/Expr.cpp +++ b/clang/lib/AST/Expr.cpp @@ -264,11 +264,14 @@ namespace { } QualType Expr::getEnumCoercedType(const ASTContext &Ctx) const { - if (isa<EnumType>(this->getType())) - return this->getType(); - else if (const auto *ECD = this->getEnumConstantDecl()) - return Ctx.getTypeDeclType(cast<EnumDecl>(ECD->getDeclContext())); - return this->getType(); + if (isa<EnumType>(getType())) + return getType(); + if (const auto *ECD = getEnumConstantDecl()) { + const auto *ED = cast<EnumDecl>(ECD->getDeclContext()); + if (ED->isCompleteDefinition()) + return Ctx.getTypeDeclType(ED); + } + return getType(); } SourceLocation Expr::getExprLoc() const { diff --git a/clang/test/Sema/enum-constant-type.cpp b/clang/test/Sema/enum-constant-type.cpp new file mode 100644 index 00000000000000..5db3a859a39599 --- /dev/null +++ b/clang/test/Sema/enum-constant-type.cpp @@ -0,0 +1,12 @@ +// RUN: %clang_cc1 -x c++ -fsyntax-only -verify %s -Wenum-compare +// expected-no-diagnostics + +enum E1 { + E11 = 0 +}; + +enum E2 { + E21 = 0, + E22 = E11, + E23 = E21 + E22 +}; diff --git a/clang/test/Sema/warn-compare-enum-types-mismatch.c b/clang/test/Sema/warn-compare-enum-types-mismatch.c index 2b72aae16b977a..85d218e3213b2d 100644 --- a/clang/test/Sema/warn-compare-enum-types-mismatch.c +++ b/clang/test/Sema/warn-compare-enum-types-mismatch.c @@ -1,12 +1,19 @@ // RUN: %clang_cc1 -x c -fsyntax-only -verify -Wenum-compare -Wno-unused-comparison %s // RUN: %clang_cc1 -x c++ -fsyntax-only -verify -Wenum-compare -Wno-unused-comparison %s +// In C enumerators (i.e enumeration constants) have type int (until C23). In order to support diagnostics such as +// -Wenum-compare we pretend they have the type of their enumeration. + typedef enum EnumA { A } EnumA; enum EnumB { - B + B, + B1 = 1, + // In C++ this comparison doesnt warn as enumerators dont have the type of their enumeration before the closing + // brace. We mantain the same behavior in C. + B2 = A == B1 }; enum { _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits