[clang] f8fab21 - [Clang][Sema] Fix type of enumerators in incomplete enumerations (#84068)
via cfe-commits
cfe-commits at lists.llvm.org
Tue Mar 12 07:21:39 PDT 2024
Author: Kupa-Martin
Date: 2024-03-12T10:21:34-04:00
New Revision: f8fab2126ffab713f4ab4619360b6941be6d4e35
URL: https://github.com/llvm/llvm-project/commit/f8fab2126ffab713f4ab4619360b6941be6d4e35
DIFF: https://github.com/llvm/llvm-project/commit/f8fab2126ffab713f4ab4619360b6941be6d4e35.diff
LOG: [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
Added:
clang/test/Sema/enum-constant-type.cpp
Modified:
clang/lib/AST/Expr.cpp
clang/test/Sema/warn-compare-enum-types-mismatch.c
Removed:
################################################################################
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..47dd592488e6dc 100644
--- a/clang/test/Sema/warn-compare-enum-types-mismatch.c
+++ b/clang/test/Sema/warn-compare-enum-types-mismatch.c
@@ -1,12 +1,21 @@
// 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 {
More information about the cfe-commits
mailing list