https://github.com/zebullax updated https://github.com/llvm/llvm-project/pull/216460
>From 59284200a3e2e65ec041fba72aaf0339e374c755 Mon Sep 17 00:00:00 2001 From: zebullax <[email protected]> Date: Sat, 15 Aug 2026 16:02:54 +0900 Subject: [PATCH 1/3] Improve scoped enum printer --- clang/lib/CodeGen/CGExpr.cpp | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp index 9201e40bc13a1..c8ac2fd53fc82 100644 --- a/clang/lib/CodeGen/CGExpr.cpp +++ b/clang/lib/CodeGen/CGExpr.cpp @@ -3959,18 +3959,27 @@ llvm::Constant *CodeGenFunction::EmitCheckTypeDescriptor(QualType T) { uint16_t TypeInfo = 0; bool IsBitInt = false; - if (T->isIntegerType()) { + // isIntegerType() never holds for scoped enums, and getAs<BitIntType> can't + // see through the EnumType node to a __BitInt underlying type even for + // unscoped enums. + QualType ValueTy = T; + if (const EnumType *ET = T->getAs<EnumType>()) { + if (ET->getDecl()->isComplete()) + ValueTy = ET->getDecl()->getIntegerType(); + } + + if (ValueTy->isIntegerType()) { TypeKind = TK_Integer; - TypeInfo = (llvm::Log2_32(getContext().getTypeSize(T)) << 1) | - (T->isSignedIntegerType() ? 1 : 0); + TypeInfo = (llvm::Log2_32(getContext().getTypeSize(ValueTy)) << 1) | + (ValueTy->isSignedIntegerType() ? 1 : 0); // Follow suggestion from discussion of issue 64100. // So we can write the exact amount of bits in TypeName after '\0' // making it <diagnostic-like type name>.'\0'.<32-bit width>. - if (T->isSignedIntegerType() && T->getAs<BitIntType>()) { + if (ValueTy->isSignedIntegerType() && ValueTy->getAs<BitIntType>()) { // Do a sanity checks as we are using 32-bit type to store bit length. - assert(getContext().getTypeSize(T) > 0 && + assert(getContext().getTypeSize(ValueTy) > 0 && " non positive amount of bits in __BitInt type"); - assert(getContext().getTypeSize(T) <= 0xFFFFFFFF && + assert(getContext().getTypeSize(ValueTy) <= 0xFFFFFFFF && " too many bits in __BitInt type"); // Redefine TypeKind with the actual __BitInt type if we have signed @@ -3994,7 +4003,7 @@ llvm::Constant *CodeGenFunction::EmitCheckTypeDescriptor(QualType T) { // The Structure is: 0 to end the string, 32 bit unsigned integer in target // endianness, zero. char S[6] = {'\0', '\0', '\0', '\0', '\0', '\0'}; - const auto *EIT = T->castAs<BitIntType>(); + const auto *EIT = ValueTy->castAs<BitIntType>(); uint32_t Bits = EIT->getNumBits(); llvm::support::endian::write32(S + 1, Bits, getTarget().isBigEndian() >From 50fd4cfd4f816d1c0b8a162fe47ab7100775cde1 Mon Sep 17 00:00:00 2001 From: zebullax <[email protected]> Date: Sat, 15 Aug 2026 16:04:42 +0900 Subject: [PATCH 2/3] Update error message for enum value check --- compiler-rt/test/ubsan/TestCases/Misc/enum.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler-rt/test/ubsan/TestCases/Misc/enum.cpp b/compiler-rt/test/ubsan/TestCases/Misc/enum.cpp index 2684029c2960b..b51347f07c050 100644 --- a/compiler-rt/test/ubsan/TestCases/Misc/enum.cpp +++ b/compiler-rt/test/ubsan/TestCases/Misc/enum.cpp @@ -25,7 +25,7 @@ int main(int argc, char **argv) { return ((int)e1 != -1) & ((int)e2 != -1) & // CHECK: error: load of value 4294967295, which is not a valid value for type 'E' ((int)e3 != -1) & ((int)e4 == 1) & - // CHECK: error: load of value <unknown>, which is not a valid value for type 'enum EBool' + // CHECK: error: load of value 255, which is not a valid value for type 'enum EBool' ((int)e5 == 2) & ((int)e6 == 1) & // CHECK: error: load of value 2, which is not a valid value for type 'EEmpty' ((int)e7 == 2); >From e1276090dd75b3a2192c6cdd6523c4253cf6cd30 Mon Sep 17 00:00:00 2001 From: acassagnes <[email protected]> Date: Mon, 17 Aug 2026 10:52:27 +0900 Subject: [PATCH 3/3] Use original T as much as possible Signed-off-by: acassagnes <[email protected]> --- clang/lib/CodeGen/CGExpr.cpp | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp index c8ac2fd53fc82..d7cf52d24474f 100644 --- a/clang/lib/CodeGen/CGExpr.cpp +++ b/clang/lib/CodeGen/CGExpr.cpp @@ -3962,24 +3962,23 @@ llvm::Constant *CodeGenFunction::EmitCheckTypeDescriptor(QualType T) { // isIntegerType() never holds for scoped enums, and getAs<BitIntType> can't // see through the EnumType node to a __BitInt underlying type even for // unscoped enums. - QualType ValueTy = T; - if (const EnumType *ET = T->getAs<EnumType>()) { + QualType BackupT = T; + if (const EnumType *ET = T->getAs<EnumType>()) if (ET->getDecl()->isComplete()) - ValueTy = ET->getDecl()->getIntegerType(); - } + T = ET->getDecl()->getIntegerType(); - if (ValueTy->isIntegerType()) { + if (T->isIntegerType()) { TypeKind = TK_Integer; - TypeInfo = (llvm::Log2_32(getContext().getTypeSize(ValueTy)) << 1) | - (ValueTy->isSignedIntegerType() ? 1 : 0); + TypeInfo = (llvm::Log2_32(getContext().getTypeSize(T)) << 1) | + (T->isSignedIntegerType() ? 1 : 0); // Follow suggestion from discussion of issue 64100. // So we can write the exact amount of bits in TypeName after '\0' // making it <diagnostic-like type name>.'\0'.<32-bit width>. - if (ValueTy->isSignedIntegerType() && ValueTy->getAs<BitIntType>()) { + if (T->isSignedIntegerType() && T->getAs<BitIntType>()) { // Do a sanity checks as we are using 32-bit type to store bit length. - assert(getContext().getTypeSize(ValueTy) > 0 && + assert(getContext().getTypeSize(T) > 0 && " non positive amount of bits in __BitInt type"); - assert(getContext().getTypeSize(ValueTy) <= 0xFFFFFFFF && + assert(getContext().getTypeSize(T) <= 0xFFFFFFFF && " too many bits in __BitInt type"); // Redefine TypeKind with the actual __BitInt type if we have signed @@ -3996,14 +3995,14 @@ llvm::Constant *CodeGenFunction::EmitCheckTypeDescriptor(QualType T) { // optionally an 'aka'. SmallString<32> Buffer; CGM.getDiags().ConvertArgToString(DiagnosticsEngine::ak_qualtype, - (intptr_t)T.getAsOpaquePtr(), StringRef(), - StringRef(), {}, Buffer, {}); + (intptr_t)BackupT.getAsOpaquePtr(), + StringRef(), StringRef(), {}, Buffer, {}); if (IsBitInt) { // The Structure is: 0 to end the string, 32 bit unsigned integer in target // endianness, zero. char S[6] = {'\0', '\0', '\0', '\0', '\0', '\0'}; - const auto *EIT = ValueTy->castAs<BitIntType>(); + const auto *EIT = T->castAs<BitIntType>(); uint32_t Bits = EIT->getNumBits(); llvm::support::endian::write32(S + 1, Bits, getTarget().isBigEndian() @@ -4026,7 +4025,7 @@ llvm::Constant *CodeGenFunction::EmitCheckTypeDescriptor(QualType T) { CGM.getSanitizerMetadata()->disableSanitizerForGlobal(GV); // Remember the descriptor for this type. - CGM.setTypeDescriptorInMap(T, GV); + CGM.setTypeDescriptorInMap(BackupT, GV); return GV; } _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
