[clang] [compiler-rt] Revert "[ubsan] Display correct runtime messages for negative _BitInt" (PR #96239)

via llvm-commits llvm-commits at lists.llvm.org
Thu Jun 20 14:40:58 PDT 2024


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-compiler-rt-sanitizer

@llvm/pr-subscribers-clang-codegen

Author: None (earnol)

<details>
<summary>Changes</summary>

Reverts llvm/llvm-project#<!-- -->93612 due to the issues with ppc64le platform.

---
Full diff: https://github.com/llvm/llvm-project/pull/96239.diff


5 Files Affected:

- (modified) clang/lib/CodeGen/CGExpr.cpp (+5-54) 
- (modified) compiler-rt/lib/ubsan/ubsan_value.cpp (+7-10) 
- (modified) compiler-rt/lib/ubsan/ubsan_value.h (+1-33) 
- (removed) compiler-rt/test/ubsan/TestCases/Integer/bit-int-pass.c (-39) 
- (removed) compiler-rt/test/ubsan/TestCases/Integer/bit-int.c (-169) 


``````````diff
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));
-}

``````````

</details>


https://github.com/llvm/llvm-project/pull/96239


More information about the llvm-commits mailing list