Skip to content

Commit

Permalink
Revert "[ubsan] Display correct runtime messages for negative _BitInt" (
Browse files Browse the repository at this point in the history
llvm#96239)

Reverts llvm#93612 due to the issues with ppc64le platform.
  • Loading branch information
earnol authored Jun 21, 2024
1 parent 8cf3988 commit 138ea7d
Show file tree
Hide file tree
Showing 5 changed files with 13 additions and 305 deletions.
59 changes: 5 additions & 54 deletions clang/lib/CodeGen/CGExpr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@
#include "llvm/IR/MatrixBuilder.h"
#include "llvm/Passes/OptimizationLevel.h"
#include "llvm/Support/ConvertUTF.h"
#include "llvm/Support/Endian.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/SaveAndRestore.h"
Expand All @@ -65,22 +64,6 @@ static llvm::cl::opt<bool> ClSanitizeGuardChecks(
"ubsan-guard-checks", llvm::cl::Optional,
llvm::cl::desc("Guard UBSAN checks with `llvm.allow.ubsan.check()`."));

//===--------------------------------------------------------------------===//
// Defines for metadata
//===--------------------------------------------------------------------===//

// Those values are crucial to be the SAME as in ubsan runtime library.
enum VariableTypeDescriptorKind : uint16_t {
/// An integer type.
TK_Integer = 0x0000,
/// A floating-point type.
TK_Float = 0x0001,
/// An _BitInt(N) type.
TK_BitInt = 0x0002,
/// Any other type. The value representation is unspecified.
TK_Unknown = 0xffff
};

//===--------------------------------------------------------------------===//
// Miscellaneous Helper Methods
//===--------------------------------------------------------------------===//
Expand Down Expand Up @@ -3315,40 +3298,22 @@ LValue CodeGenFunction::EmitPredefinedLValue(const PredefinedExpr *E) {
/// { i16 TypeKind, i16 TypeInfo }
/// \endcode
///
/// followed by an array of i8 containing the type name with extra information
/// for BitInt. TypeKind is TK_Integer(0) for an integer, TK_Float(1) for a
/// floating point value, TK_BitInt(2) for BitInt and TK_Unknown(0xFFFF) for
/// anything else.
/// followed by an array of i8 containing the type name. TypeKind is 0 for an
/// integer, 1 for a floating point value, and -1 for anything else.
llvm::Constant *CodeGenFunction::EmitCheckTypeDescriptor(QualType T) {
// Only emit each type's descriptor once.
if (llvm::Constant *C = CGM.getTypeDescriptorFromMap(T))
return C;

uint16_t TypeKind = TK_Unknown;
uint16_t TypeKind = -1;
uint16_t TypeInfo = 0;
bool IsBitInt = false;

if (T->isIntegerType()) {
TypeKind = TK_Integer;
TypeKind = 0;
TypeInfo = (llvm::Log2_32(getContext().getTypeSize(T)) << 1) |
(T->isSignedIntegerType() ? 1 : 0);
// Follow suggestion from https://github.com/llvm/llvm-project/issues/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>()) {
// Do a sanity checks as we are using 32-bit type to store bit length.
assert((getContext().getTypeSize(T) > 0) &&
" non positive amount of bits in __BitInt type");
assert((getContext().getTypeSize(T) <= 0xFFFFFFFF) &&
" too many bits in __BitInt type");

// Redefine TypeKind with the actual __BitInt type if we have signed
// BitInt.
TypeKind = TK_BitInt;
IsBitInt = true;
}
} else if (T->isFloatingType()) {
TypeKind = TK_Float;
TypeKind = 1;
TypeInfo = getContext().getTypeSize(T);
}

Expand All @@ -3359,20 +3324,6 @@ llvm::Constant *CodeGenFunction::EmitCheckTypeDescriptor(QualType T) {
DiagnosticsEngine::ak_qualtype, (intptr_t)T.getAsOpaquePtr(), StringRef(),
StringRef(), std::nullopt, Buffer, std::nullopt);

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 = T->castAs<BitIntType>();
uint32_t Bits = EIT->getNumBits();
llvm::support::endian::write32(S + 1, Bits,
getTarget().isBigEndian()
? llvm::endianness::big
: llvm::endianness::little);
StringRef str = StringRef(S, sizeof(S) / sizeof(decltype(S[0])));
Buffer.append(str);
}

llvm::Constant *Components[] = {
Builder.getInt16(TypeKind), Builder.getInt16(TypeInfo),
llvm::ConstantDataArray::getString(getLLVMContext(), Buffer)
Expand Down
17 changes: 7 additions & 10 deletions compiler-rt/lib/ubsan/ubsan_value.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,21 +67,18 @@ const char *__ubsan::getObjCClassName(ValueHandle Pointer) {

SIntMax Value::getSIntValue() const {
CHECK(getType().isSignedIntegerTy());
// Val was zero-extended to ValueHandle. Sign-extend from original width
// to SIntMax.
const unsigned ExtraBits =
sizeof(SIntMax) * 8 - getType().getIntegerBitCount();
if (isInlineInt()) {
// Val was zero-extended to ValueHandle. Sign-extend from original width
// to SIntMax.
const unsigned ExtraBits =
sizeof(SIntMax) * 8 - getType().getIntegerBitWidth();
return SIntMax(UIntMax(Val) << ExtraBits) >> ExtraBits;
}
if (getType().getIntegerBitWidth() == 64) {
return SIntMax(UIntMax(*reinterpret_cast<s64 *>(Val)) << ExtraBits) >>
ExtraBits;
}
if (getType().getIntegerBitWidth() == 64)
return *reinterpret_cast<s64*>(Val);
#if HAVE_INT128_T
if (getType().getIntegerBitWidth() == 128)
return SIntMax(UIntMax(*reinterpret_cast<s128 *>(Val)) << ExtraBits) >>
ExtraBits;
return *reinterpret_cast<s128*>(Val);
#else
if (getType().getIntegerBitWidth() == 128)
UNREACHABLE("libclang_rt.ubsan was built without __int128 support");
Expand Down
34 changes: 1 addition & 33 deletions compiler-rt/lib/ubsan/ubsan_value.h
Original file line number Diff line number Diff line change
Expand Up @@ -103,13 +103,6 @@ class TypeDescriptor {
/// representation is that of bitcasting the floating-point value to an
/// integer type.
TK_Float = 0x0001,
/// An _BitInt(N) type. Lowest bit is 1 for a signed value, 0 for an
/// unsigned value. Remaining bits are log_2(bit_width). The value
/// representation is the integer itself if it fits into a ValueHandle, and
/// a pointer to the integer otherwise. TypeName contains the true width
/// of the type for the signed _BitInt(N) type stored after zero bit after
/// TypeName as 32-bit unsigned integer.
TK_BitInt = 0x0002,
/// Any other type. The value representation is unspecified.
TK_Unknown = 0xffff
};
Expand All @@ -120,15 +113,10 @@ class TypeDescriptor {
return static_cast<Kind>(TypeKind);
}

bool isIntegerTy() const {
return getKind() == TK_Integer || getKind() == TK_BitInt;
}
bool isBitIntTy() const { return getKind() == TK_BitInt; }

bool isIntegerTy() const { return getKind() == TK_Integer; }
bool isSignedIntegerTy() const {
return isIntegerTy() && (TypeInfo & 1);
}
bool isSignedBitIntTy() const { return isBitIntTy() && (TypeInfo & 1); }
bool isUnsignedIntegerTy() const {
return isIntegerTy() && !(TypeInfo & 1);
}
Expand All @@ -137,26 +125,6 @@ class TypeDescriptor {
return 1 << (TypeInfo >> 1);
}

const char *getBitIntBitCountPointer() const {
CHECK(isBitIntTy());
CHECK(isSignedBitIntTy());
// Scan Name for zero and return the next address
const char *p = getTypeName();
while (*p != '\0') {
++p;
}
// Return the next address
return p + 1;
}

unsigned getIntegerBitCount() const {
CHECK(isIntegerTy());
if (isSignedBitIntTy())
return *reinterpret_cast<const u32 *>(getBitIntBitCountPointer());
else
return getIntegerBitWidth();
}

bool isFloatTy() const { return getKind() == TK_Float; }
unsigned getFloatBitWidth() const {
CHECK(isFloatTy());
Expand Down
39 changes: 0 additions & 39 deletions compiler-rt/test/ubsan/TestCases/Integer/bit-int-pass.c

This file was deleted.

169 changes: 0 additions & 169 deletions compiler-rt/test/ubsan/TestCases/Integer/bit-int.c

This file was deleted.

0 comments on commit 138ea7d

Please sign in to comment.