[clang] [compiler-rt] Revert "[ubsan] Display correct runtime messages for negative _BitInt" (PR #96239)
via cfe-commits
cfe-commits at lists.llvm.org
Thu Jun 20 14:40:29 PDT 2024
https://github.com/earnol created https://github.com/llvm/llvm-project/pull/96239
Reverts llvm/llvm-project#93612 due to the issues with ppc64le platform.
>From 508bc2e44b59c26955e9b1226f84b4ff2cc05fee Mon Sep 17 00:00:00 2001
From: earnol <earnol at users.noreply.github.com>
Date: Thu, 20 Jun 2024 17:39:06 -0400
Subject: [PATCH] Revert "[ubsan] Display correct runtime messages for negative
_BitInt (#93612)"
This reverts commit 49001d584c69726eb7b5069468c5216da3fc3263.
---
clang/lib/CodeGen/CGExpr.cpp | 59 +-----
compiler-rt/lib/ubsan/ubsan_value.cpp | 17 +-
compiler-rt/lib/ubsan/ubsan_value.h | 34 +---
.../ubsan/TestCases/Integer/bit-int-pass.c | 39 ----
.../test/ubsan/TestCases/Integer/bit-int.c | 169 ------------------
5 files changed, 13 insertions(+), 305 deletions(-)
delete mode 100644 compiler-rt/test/ubsan/TestCases/Integer/bit-int-pass.c
delete mode 100644 compiler-rt/test/ubsan/TestCases/Integer/bit-int.c
diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp
index 55b2b4337fab8..3dfe5e09c778d 100644
--- a/clang/lib/CodeGen/CGExpr.cpp
+++ b/clang/lib/CodeGen/CGExpr.cpp
@@ -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"
@@ -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
//===--------------------------------------------------------------------===//
@@ -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);
}
@@ -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)
diff --git a/compiler-rt/lib/ubsan/ubsan_value.cpp b/compiler-rt/lib/ubsan/ubsan_value.cpp
index 6e88ebaf34d4b..dc61e5b939d95 100644
--- a/compiler-rt/lib/ubsan/ubsan_value.cpp
+++ b/compiler-rt/lib/ubsan/ubsan_value.cpp
@@ -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");
diff --git a/compiler-rt/lib/ubsan/ubsan_value.h b/compiler-rt/lib/ubsan/ubsan_value.h
index b8ca3a0b1d476..e0957276dd241 100644
--- a/compiler-rt/lib/ubsan/ubsan_value.h
+++ b/compiler-rt/lib/ubsan/ubsan_value.h
@@ -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
};
@@ -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);
}
@@ -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());
diff --git a/compiler-rt/test/ubsan/TestCases/Integer/bit-int-pass.c b/compiler-rt/test/ubsan/TestCases/Integer/bit-int-pass.c
deleted file mode 100644
index b9e43c482edc0..0000000000000
--- a/compiler-rt/test/ubsan/TestCases/Integer/bit-int-pass.c
+++ /dev/null
@@ -1,39 +0,0 @@
-// RUN: %clang -Wno-constant-conversion -Wno-array-bounds -Wno-division-by-zero -Wno-shift-negative-value -Wno-shift-count-negative -Wno-int-to-pointer-cast -O0 -fsanitize=alignment,array-bounds,bool,float-cast-overflow,implicit-integer-sign-change,implicit-signed-integer-truncation,implicit-unsigned-integer-truncation,integer-divide-by-zero,nonnull-attribute,null,nullability-arg,nullability-assign,nullability-return,pointer-overflow,returns-nonnull-attribute,shift-base,shift-exponent,signed-integer-overflow,unreachable,unsigned-integer-overflow,unsigned-shift-base,vla-bound %s -o %t1 && %run %t1 2>&1 | FileCheck %s
-
-#include <stdint.h>
-#include <stdio.h>
-
-// In this test there is an expectation of assignment of _BitInt not producing any output.
-uint32_t nullability_arg(_BitInt(37) *_Nonnull x)
- __attribute__((no_sanitize("address"))) {
- _BitInt(37) y = *(_BitInt(37) *)&x;
- return y;
-}
-
-// In this test there is an expectation of ubsan not triggeting on returning random address which is inside address space of the process.
-_BitInt(37) nonnull_attribute(__attribute__((nonnull)) _BitInt(37) * x)
- __attribute__((no_sanitize("address"))) {
- return *(_BitInt(37) *)&x;
-}
-
-// In this test there is an expectation of assignment of uint32_t from "invalid" _BitInt is not producing any output.
-uint32_t nullability_assign(_BitInt(7) * x)
- __attribute__((no_sanitize("address"))) {
- _BitInt(7) *_Nonnull y = x;
- int32_t r = *(_BitInt(7) *)&y;
- return (r > 0) ? r : 0;
-}
-
-// In those examples the file is expected to compile&run with no diagnostics
-// CHECK-NOT: runtime error:
-
-int main(int argc, char **argv) {
- // clang-format off
- uint64_t result =
- 1ULL +
- nullability_arg((_BitInt(37) *)argc) +
- ((uint64_t)nonnull_attribute((_BitInt(37) *)argc) & 0xFFFFFFFF) +
- nullability_assign((_BitInt(7) *)argc);
- // clang-format on
- printf("%u\n", (uint32_t)(result & 0xFFFFFFFF));
-}
diff --git a/compiler-rt/test/ubsan/TestCases/Integer/bit-int.c b/compiler-rt/test/ubsan/TestCases/Integer/bit-int.c
deleted file mode 100644
index f2282e6b5a08e..0000000000000
--- a/compiler-rt/test/ubsan/TestCases/Integer/bit-int.c
+++ /dev/null
@@ -1,169 +0,0 @@
-// RUN: %clang -Wno-constant-conversion -Wno-array-bounds -Wno-division-by-zero -Wno-shift-negative-value -Wno-shift-count-negative -Wno-int-to-pointer-cast -O0 -fsanitize=alignment,array-bounds,bool,float-cast-overflow,implicit-integer-sign-change,implicit-signed-integer-truncation,implicit-unsigned-integer-truncation,integer-divide-by-zero,nonnull-attribute,null,nullability-arg,nullability-assign,nullability-return,pointer-overflow,returns-nonnull-attribute,shift-base,shift-exponent,signed-integer-overflow,unreachable,unsigned-integer-overflow,unsigned-shift-base,vla-bound %s -o %t1 && %run %t1 2>&1 | FileCheck %s --check-prefix=RUNTIME
-// RUN: %clang -Wno-constant-conversion -Wno-array-bounds -Wno-division-by-zero -Wno-shift-negative-value -Wno-shift-count-negative -Wno-int-to-pointer-cast -fsanitize=array-bounds,enum,float-cast-overflow,integer-divide-by-zero,implicit-unsigned-integer-truncation,implicit-signed-integer-truncation,implicit-integer-sign-change,unsigned-integer-overflow,signed-integer-overflow,shift-base,shift-exponent -O0 -S -emit-llvm -o - %s | FileCheck %s --check-prefix=IR
-
-#include <stdint.h>
-#include <stdio.h>
-
-uint32_t float_divide_by_zero() {
- float f = 1.0f / 0.0f;
- // IR: constant { i16, i16, [8 x i8] } { i16 1, i16 32, [8 x i8] c"'float'\00" }
- _BitInt(37) r = (_BitInt(37))f;
- // RUNTIME: {{.*}}bit-int.c:[[@LINE-1]]:19: runtime error: inf is outside the range of representable values of type
- // IR: constant { i16, i16, [20 x i8] } { i16 2, i16 13, [20 x i8] c"'_BitInt(37)'\00%\00\00\00\00\00" }
- return r;
-}
-
-uint32_t integer_divide_by_zero() __attribute__((no_sanitize("memory"))) {
- _BitInt(37) x = 1 / 0;
- // RUNTIME: {{.*}}bit-int.c:[[@LINE-1]]:21: runtime error: division by zero
- // IR: constant { i16, i16, [32 x i8] } { i16 0, i16 10, [32 x i8] c"'uint32_t' (aka 'unsigned int')\00" }
- return x;
-}
-
-uint32_t implicit_unsigned_integer_truncation() {
- unsigned _BitInt(37) x = 2U;
- x += float_divide_by_zero();
- x += integer_divide_by_zero();
- x = x + 0xFFFFFFFFFFFFFFFFULL;
- // RUNTIME: {{.*}}bit-int.c:[[@LINE-1]]:9: runtime error: unsigned integer overflow:
- // IR: constant { i16, i16, [23 x i8] } { i16 0, i16 12, [23 x i8] c"'unsigned _BitInt(37)'\00" }
- uint32_t r = x & 0xFFFFFFFF;
- return r;
-}
-
-uint32_t pointer_overflow() __attribute__((no_sanitize("address"))) {
- _BitInt(37) *x = (_BitInt(37) *)1;
- _BitInt(37) *y = x - 1;
- // RUNTIME: {{.*}}bit-int.c:[[@LINE-1]]:22: runtime error: pointer index expression with base
- uint32_t r = *(_BitInt(37) *)&y;
- // RUNTIME: {{.*}}bit-int.c:[[@LINE-1]]:16: runtime error: implicit conversion from type
- return r;
-}
-
-uint32_t vla_bound(_BitInt(37) x) {
- _BitInt(37) a[x - 1];
- // RUNTIME: {{.*}}bit-int.c:[[@LINE-1]]:17: runtime error: variable length array bound evaluates to non-positive value
- return 0;
-}
-
-uint32_t unsigned_shift_base() {
- unsigned _BitInt(37) x = ~0U << 1;
- // RUNTIME: {{.*}}bit-int.c:[[@LINE-1]]:32: runtime error: left shift of 4294967295 by 1 places cannot be represented in type
- return x;
-}
-
-uint32_t array_bounds() {
- _BitInt(37) x[4];
- _BitInt(37) y = x[10];
- // RUNTIME: {{.*}}bit-int.c:[[@LINE-1]]:19: runtime error: index 10 out of bounds for type
- // IR: constant { i16, i16, [17 x i8] } { i16 -1, i16 0, [17 x i8] c"'_BitInt(37)[4]'\00" }
- return (uint32_t)y;
-}
-
-uint32_t float_cast_overflow() {
- float a = 100000000.0f;
- _BitInt(7) b = (_BitInt(7))a;
- // RUNTIME: {{.*}}bit-int.c:[[@LINE-1]]:18: runtime error: 1e+08 is outside the range of representable values of type
- // IR: constant { i16, i16, [19 x i8] } { i16 2, i16 7, [19 x i8] c"'_BitInt(7)'\00\07\00\00\00\00\00" }
- return b;
-}
-
-uint32_t implicit_integer_sign_change(unsigned _BitInt(37) x) {
- _BitInt(37) r = x;
- // RUNTIME: {{.*}}bit-int.c:[[@LINE-1]]:19: runtime error: implicit conversion from type '{{[^']+}}' of value
- return r & 0xFFFFFFFF;
-}
-
-_BitInt(13) implicit_signed_integer_truncation() {
- _BitInt(73) x = (_BitInt(73)) ~((~0UL) >> 1);
- return x;
- // RUNTIME: {{.*}}bit-int.c:[[@LINE-1]]:10: runtime error: implicit conversion from type
- // IR: constant { i16, i16, [20 x i8] } { i16 2, i16 {{([[:xdigit:]]{2})}}, [20 x i8] c"'_BitInt(73)'\00I\00\00\00\00\00" }
- // IR: constant { i16, i16, [20 x i8] } { i16 2, i16 9, [20 x i8] c"'_BitInt(13)'\00\0D\00\00\00\00\00" }
-}
-
-_BitInt(37) shift_exponent() {
- _BitInt(37) x = 1 << (-1);
- // RUNTIME: {{.*}}bit-int.c:[[@LINE-1]]:21: runtime error: shift exponent -1 is negative
- return x;
-}
-
-_BitInt(37) shift_base() {
- _BitInt(37) x = (-1) << 1;
- // RUNTIME: {{.*}}bit-int.c:[[@LINE-1]]:24: runtime error: left shift of negative value -1
- return x;
-}
-
-uint32_t negative_shift1(unsigned _BitInt(37) x) {
- _BitInt(9) c = -2;
- return x >> c;
- // RUNTIME: {{.*}}bit-int.c:[[@LINE-1]]:12: runtime error: shift exponent -2 is negative
- // IR: constant { i16, i16, [19 x i8] } { i16 2, i16 9, [19 x i8] c"'_BitInt(9)'\00\09\00\00\00\00\00" }
-}
-
-uint32_t negative_shift2(unsigned _BitInt(37) x) {
- _BitInt(17) c = -2;
- return x >> c;
- // RUNTIME: {{.*}}bit-int.c:[[@LINE-1]]:12: runtime error: shift exponent -2 is negative
- // IR: constant { i16, i16, [20 x i8] } { i16 2, i16 11, [20 x i8] c"'_BitInt(17)'\00\11\00\00\00\00\00" }
-}
-
-uint32_t negative_shift3(unsigned _BitInt(37) x) {
- _BitInt(34) c = -2;
- return x >> c;
- // RUNTIME: {{.*}}bit-int.c:[[@LINE-1]]:12: runtime error: shift exponent -2 is negative
- // IR: constant { i16, i16, [20 x i8] } { i16 2, i16 13, [20 x i8] c"'_BitInt(34)'\00\22\00\00\00\00\00" }
-}
-
-uint32_t negative_shift4(unsigned _BitInt(37) x) {
- int64_t c = -2;
- return x >> c;
- // RUNTIME: {{.*}}bit-int.c:[[@LINE-1]]:12: runtime error: shift exponent -2 is negative
-}
-
-uint32_t negative_shift5(unsigned _BitInt(37) x) {
- _BitInt(68) c = -2;
- return x >> c;
- // CHECK-R: {{.*}}bit-int.c:[[@LINE-1]]:12: runtime error: shift exponent -2 is negative
- // CHECK-IR: constant { i16, i16, [20 x i8] } { i16 2, i16 {{([[:xdigit:]]{2})}}, [20 x i8] c"'_BitInt(68)'\00D\00\00\00\00\00" }
-}
-
-uint32_t unsigned_integer_overflow() {
- unsigned _BitInt(37) x = ~0U;
- ++x;
- return x;
- // RUNTIME: {{.*}}bit-int.c:[[@LINE-1]]:10: runtime error: implicit conversion from type
-}
-
-// In this test no run-time overflow expected, so no diagnostics here, but should be a conversion error from the negative number on return.
-uint32_t signed_integer_overflow() {
- _BitInt(37) x = (_BitInt(37)) ~((0x8FFFFFFFFFFFFFFFULL) >> 1);
- --x;
- return x;
- // RUNTIME: {{.*}}bit-int.c:[[@LINE-1]]:10: runtime error: implicit conversion from type
-}
-
-int main(int argc, char **argv) {
- // clang-format off
- uint64_t result =
- 1ULL +
- implicit_unsigned_integer_truncation() +
- pointer_overflow() +
- vla_bound(argc) +
- unsigned_shift_base() +
- (uint32_t)array_bounds() +
- float_cast_overflow() +
- implicit_integer_sign_change((unsigned _BitInt(37))(argc - 2)) +
- (uint64_t)implicit_signed_integer_truncation() +
- shift_exponent() +
- (uint32_t)shift_base() +
- negative_shift1(5) +
- negative_shift2(5) +
- negative_shift3(5) +
- negative_shift4(5) +
- negative_shift5(5) +
- unsigned_integer_overflow() +
- signed_integer_overflow();
- // clang-format on
- printf("%u\n", (uint32_t)(result & 0xFFFFFFFF));
-}
More information about the cfe-commits
mailing list