zequanwu created this revision.
zequanwu added reviewers: hans, aaron.ballman.
Herald added a project: All.
zequanwu requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

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.

This fixes https://github.com/llvm/llvm-project/issues/56560.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D130210

Files:
  clang/lib/Sema/SemaDecl.cpp
  clang/test/SemaCXX/enum-bool.cpp


Index: clang/test/SemaCXX/enum-bool.cpp
===================================================================
--- /dev/null
+++ clang/test/SemaCXX/enum-bool.cpp
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1  -fsyntax-only %s
+
+// This shouldn't crash.
+
+enum GH56560_1 : bool;
+bool GH56560_2(GH56560_1 a, GH56560_1 b) {
+    return a == b;
+}
Index: clang/lib/Sema/SemaDecl.cpp
===================================================================
--- clang/lib/Sema/SemaDecl.cpp
+++ clang/lib/Sema/SemaDecl.cpp
@@ -16194,7 +16194,11 @@
           ED->setIntegerTypeSourceInfo(TI);
         else
           ED->setIntegerType(QualType(EnumUnderlying.get<const Type *>(), 0));
-        ED->setPromotionType(ED->getIntegerType());
+        QualType EnumTy = ED->getIntegerType();
+        if (EnumTy->isPromotableIntegerType())
+          ED->setPromotionType(Context.getPromotedIntegerType(EnumTy));
+        else
+          ED->setPromotionType(EnumTy);
       }
     } else { // struct/union
       New = RecordDecl::Create(Context, Kind, SearchDC, KWLoc, Loc, Name,
@@ -16816,8 +16820,12 @@
       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();
+      if (EnumTy->isPromotableIntegerType())
+        ED->setPromotionType(Context.getPromotedIntegerType(EnumTy));
+      else
+        ED->setPromotionType(EnumTy);
       assert(ED->isComplete() && "enum with type should be complete");
     }
   } else {


Index: clang/test/SemaCXX/enum-bool.cpp
===================================================================
--- /dev/null
+++ clang/test/SemaCXX/enum-bool.cpp
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1  -fsyntax-only %s
+
+// This shouldn't crash.
+
+enum GH56560_1 : bool;
+bool GH56560_2(GH56560_1 a, GH56560_1 b) {
+    return a == b;
+}
Index: clang/lib/Sema/SemaDecl.cpp
===================================================================
--- clang/lib/Sema/SemaDecl.cpp
+++ clang/lib/Sema/SemaDecl.cpp
@@ -16194,7 +16194,11 @@
           ED->setIntegerTypeSourceInfo(TI);
         else
           ED->setIntegerType(QualType(EnumUnderlying.get<const Type *>(), 0));
-        ED->setPromotionType(ED->getIntegerType());
+        QualType EnumTy = ED->getIntegerType();
+        if (EnumTy->isPromotableIntegerType())
+          ED->setPromotionType(Context.getPromotedIntegerType(EnumTy));
+        else
+          ED->setPromotionType(EnumTy);
       }
     } else { // struct/union
       New = RecordDecl::Create(Context, Kind, SearchDC, KWLoc, Loc, Name,
@@ -16816,8 +16820,12 @@
       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();
+      if (EnumTy->isPromotableIntegerType())
+        ED->setPromotionType(Context.getPromotedIntegerType(EnumTy));
+      else
+        ED->setPromotionType(EnumTy);
       assert(ED->isComplete() && "enum with type should be complete");
     }
   } else {
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to