Skip to content

Commit

Permalink
[Clang][Sema] Fix type of enumerators in incomplete enumerations (llv…
Browse files Browse the repository at this point in the history
…m#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 llvm#81418
Fixes llvm#84712
  • Loading branch information
martinkupa authored Mar 12, 2024
1 parent afd4758 commit f8fab21
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 6 deletions.
13 changes: 8 additions & 5 deletions clang/lib/AST/Expr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
12 changes: 12 additions & 0 deletions clang/test/Sema/enum-constant-type.cpp
Original file line number Diff line number Diff line change
@@ -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
};
11 changes: 10 additions & 1 deletion clang/test/Sema/warn-compare-enum-types-mismatch.c
Original file line number Diff line number Diff line change
@@ -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 {
Expand Down

0 comments on commit f8fab21

Please sign in to comment.