blob: c8c6212c63b2ec94a889d28bc8dabc7eaf64c2dd [file] [log] [blame]
commit d870a575631d2cedab2ff237af8edd17916edc64
Author: Zequan Wu <zequanwu@google.com>
Date: Wed Jul 20 16:08:25 2022 -0700
[SemaCXX] Set promotion type for enum if its type is promotable to integer type even if it has no definition.
EnumDecl's promotion type is set either to the parsed type or calculated type
after completing its definition. When it's bool type and has no definition,
its promotion type is bool which is not allowed by clang.
Fixes #56560.
Differential Revision: https://reviews.llvm.org/D130210
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 736c299f38bb..8d2fc5331a0d 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -16209,7 +16209,10 @@ Decl *Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK,
ED->setIntegerTypeSourceInfo(TI);
else
ED->setIntegerType(QualType(EnumUnderlying.get<const Type *>(), 0));
- ED->setPromotionType(ED->getIntegerType());
+ QualType EnumTy = ED->getIntegerType();
+ ED->setPromotionType(EnumTy->isPromotableIntegerType()
+ ? Context.getPromotedIntegerType(EnumTy)
+ : EnumTy);
}
} else { // struct/union
New = RecordDecl::Create(Context, Kind, SearchDC, KWLoc, Loc, Name,
@@ -16831,8 +16834,11 @@ CreateNewDecl:
if (TypeSourceInfo *TI = EnumUnderlying.dyn_cast<TypeSourceInfo*>())
ED->setIntegerTypeSourceInfo(TI);
else
- ED->setIntegerType(QualType(EnumUnderlying.get<const Type*>(), 0));
- ED->setPromotionType(ED->getIntegerType());
+ ED->setIntegerType(QualType(EnumUnderlying.get<const Type *>(), 0));
+ QualType EnumTy = ED->getIntegerType();
+ ED->setPromotionType(EnumTy->isPromotableIntegerType()
+ ? Context.getPromotedIntegerType(EnumTy)
+ : EnumTy);
assert(ED->isComplete() && "enum with type should be complete");
}
} else {
diff --git a/clang/test/CXX/conv/conv.prom/p4.cpp b/clang/test/CXX/conv/conv.prom/p4.cpp
index 8c86d2a1838d..be422f362d6e 100644
--- a/clang/test/CXX/conv/conv.prom/p4.cpp
+++ b/clang/test/CXX/conv/conv.prom/p4.cpp
@@ -26,3 +26,10 @@ enum B2 : bool {
// FIXME: DR1407 will make this ill-formed
e = +false_ // desired-error {{conversion from 'int' to 'bool'}}
};
+
+namespace GH56560 {
+enum GH56560_1 : bool;
+bool GH56560_2(GH56560_1 a, GH56560_1 b) {
+ return a == b;
+}
+} // namespace GH56560