[SemaCXX] Set promotion type for enum if its type is promotable to integer type even...
authorZequan Wu <zequanwu@google.com>
Wed, 20 Jul 2022 23:08:25 +0000 (16:08 -0700)
committerZequan Wu <zequanwu@google.com>
Thu, 21 Jul 2022 18:23:21 +0000 (11:23 -0700)
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

clang/docs/ReleaseNotes.rst
clang/lib/Sema/SemaDecl.cpp
clang/test/CXX/conv/conv.prom/p4.cpp

index cb64cd2..d65fcdb 100644 (file)
@@ -192,6 +192,8 @@ Bug Fixes
   Fixes `Issue 56310 <https://github.com/llvm/llvm-project/issues/56310>`_.
 - Clang will now look through type sugar when checking a member function is a
   move assignment operator. Fixes `Issue 56456 <https://github.com/llvm/llvm-project/issues/56456>`_.
+- Fixed a crash when a variable with a bool enum type that has no definition
+  used in comparison operators. Fixes `Issue 56560 <https://github.com/llvm/llvm-project/issues/56560>`_.
 
 Improvements to Clang's diagnostics
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
index 736c299..8d2fc53 100644 (file)
@@ -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 {
index 8c86d2a..be422f3 100644 (file)
@@ -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