4242#include " llvm/IR/MatrixBuilder.h"
4343#include " llvm/Passes/OptimizationLevel.h"
4444#include " llvm/Support/ConvertUTF.h"
45+ #include " llvm/Support/Endian.h"
4546#include " llvm/Support/MathExtras.h"
4647#include " llvm/Support/Path.h"
4748#include " llvm/Support/SaveAndRestore.h"
@@ -65,6 +66,22 @@ static llvm::cl::opt<bool> ClSanitizeGuardChecks(
6566 " ubsan-guard-checks" , llvm::cl::Optional,
6667 llvm::cl::desc (" Guard UBSAN checks with `llvm.allow.ubsan.check()`." ));
6768
69+ // ===--------------------------------------------------------------------===//
70+ // Defines for metadata
71+ // ===--------------------------------------------------------------------===//
72+
73+ // Those values are crucial to be the SAME as in ubsan runtime library.
74+ enum VariableTypeDescriptorKind : uint16_t {
75+ // / An integer type.
76+ TK_Integer = 0x0000 ,
77+ // / A floating-point type.
78+ TK_Float = 0x0001 ,
79+ // / An _BitInt(N) type.
80+ TK_BitInt = 0x0002 ,
81+ // / Any other type. The value representation is unspecified.
82+ TK_Unknown = 0xffff
83+ };
84+
6885// ===--------------------------------------------------------------------===//
6986// Miscellaneous Helper Methods
7087// ===--------------------------------------------------------------------===//
@@ -3288,22 +3305,40 @@ LValue CodeGenFunction::EmitPredefinedLValue(const PredefinedExpr *E) {
32883305// / { i16 TypeKind, i16 TypeInfo }
32893306// / \endcode
32903307// /
3291- // / followed by an array of i8 containing the type name. TypeKind is 0 for an
3292- // / integer, 1 for a floating point value, and -1 for anything else.
3308+ // / followed by an array of i8 containing the type name with extra information
3309+ // / for BitInt. TypeKind is TK_Integer(0) for an integer, TK_Float(1) for a
3310+ // / floating point value, TK_BitInt(2) for BitInt and TK_Unknown(0xFFFF) for
3311+ // / anything else.
32933312llvm::Constant *CodeGenFunction::EmitCheckTypeDescriptor (QualType T) {
32943313 // Only emit each type's descriptor once.
32953314 if (llvm::Constant *C = CGM.getTypeDescriptorFromMap (T))
32963315 return C;
32973316
3298- uint16_t TypeKind = - 1 ;
3317+ uint16_t TypeKind = TK_Unknown ;
32993318 uint16_t TypeInfo = 0 ;
3319+ bool IsBitInt = false ;
33003320
33013321 if (T->isIntegerType ()) {
3302- TypeKind = 0 ;
3322+ TypeKind = TK_Integer ;
33033323 TypeInfo = (llvm::Log2_32 (getContext ().getTypeSize (T)) << 1 ) |
33043324 (T->isSignedIntegerType () ? 1 : 0 );
3325+ // Follow suggestion from discussion of issue 64100.
3326+ // So we can write the exact amount of bits in TypeName after '\0'
3327+ // making it <diagnostic-like type name>.'\0'.<32-bit width>.
3328+ if (T->isSignedIntegerType () && T->getAs <BitIntType>()) {
3329+ // Do a sanity checks as we are using 32-bit type to store bit length.
3330+ assert (getContext ().getTypeSize (T) > 0 &&
3331+ " non positive amount of bits in __BitInt type" );
3332+ assert (getContext ().getTypeSize (T) <= 0xFFFFFFFF &&
3333+ " too many bits in __BitInt type" );
3334+
3335+ // Redefine TypeKind with the actual __BitInt type if we have signed
3336+ // BitInt.
3337+ TypeKind = TK_BitInt;
3338+ IsBitInt = true ;
3339+ }
33053340 } else if (T->isFloatingType ()) {
3306- TypeKind = 1 ;
3341+ TypeKind = TK_Float ;
33073342 TypeInfo = getContext ().getTypeSize (T);
33083343 }
33093344
@@ -3314,6 +3349,20 @@ llvm::Constant *CodeGenFunction::EmitCheckTypeDescriptor(QualType T) {
33143349 DiagnosticsEngine::ak_qualtype, (intptr_t )T.getAsOpaquePtr (), StringRef (),
33153350 StringRef (), std::nullopt , Buffer, std::nullopt );
33163351
3352+ if (IsBitInt) {
3353+ // The Structure is: 0 to end the string, 32 bit unsigned integer in target
3354+ // endianness, zero.
3355+ char S[6 ] = {' \0 ' , ' \0 ' , ' \0 ' , ' \0 ' , ' \0 ' , ' \0 ' };
3356+ const auto *EIT = T->castAs <BitIntType>();
3357+ uint32_t Bits = EIT->getNumBits ();
3358+ llvm::support::endian::write32 (S + 1 , Bits,
3359+ getTarget ().isBigEndian ()
3360+ ? llvm::endianness::big
3361+ : llvm::endianness::little);
3362+ StringRef Str = StringRef (S, sizeof (S) / sizeof (decltype (S[0 ])));
3363+ Buffer.append (Str);
3364+ }
3365+
33173366 llvm::Constant *Components[] = {
33183367 Builder.getInt16 (TypeKind), Builder.getInt16 (TypeInfo),
33193368 llvm::ConstantDataArray::getString (getLLVMContext (), Buffer)
0 commit comments