Unverified Commit 56dab2cb authored by Timm Baeder's avatar Timm Baeder Committed by GitHub
Browse files

[clang][Interp] Fix truncateCast() (#69911)

The added test case used to fail because we converted the LHS to `-1`.
parent 849297c9
Loading
Loading
Loading
Loading
+15 −12
Original line number Diff line number Diff line
@@ -35,10 +35,18 @@ private:
  friend IntegralAP<!Signed>;
  APInt V;

  template <typename T> static T truncateCast(const APInt &V) {
  template <typename T, bool InputSigned>
  static T truncateCast(const APInt &V) {
    constexpr unsigned BitSize = sizeof(T) * 8;
    if (BitSize >= V.getBitWidth())
      return std::is_signed_v<T> ? V.getSExtValue() : V.getZExtValue();
    if (BitSize >= V.getBitWidth()) {
      APInt Extended;
      if constexpr (InputSigned)
        Extended = V.sext(BitSize);
      else
        Extended = V.zext(BitSize);
      return std::is_signed_v<T> ? Extended.getSExtValue()
                                 : Extended.getZExtValue();
    }

    return std::is_signed_v<T> ? V.trunc(BitSize).getSExtValue()
                               : V.trunc(BitSize).getZExtValue();
@@ -80,15 +88,10 @@ public:
    return V.ult(RHS.V);
  }

  explicit operator bool() const { return !V.isZero(); }
  explicit operator int8_t() const { return truncateCast<int8_t>(V); }
  explicit operator uint8_t() const { return truncateCast<uint8_t>(V); }
  explicit operator int16_t() const { return truncateCast<int16_t>(V); }
  explicit operator uint16_t() const { return truncateCast<uint16_t>(V); }
  explicit operator int32_t() const { return truncateCast<int32_t>(V); }
  explicit operator uint32_t() const { return truncateCast<uint32_t>(V); }
  explicit operator int64_t() const { return truncateCast<int64_t>(V); }
  explicit operator uint64_t() const { return truncateCast<uint64_t>(V); }
  template <typename Ty, typename = std::enable_if_t<std::is_integral_v<Ty>>>
  explicit operator Ty() const {
    return truncateCast<Ty, Signed>(V);
  }

  template <typename T> static IntegralAP from(T Value, unsigned NumBits = 0) {
    assert(NumBits > 0);
+3 −0
Original line number Diff line number Diff line
@@ -27,6 +27,9 @@ static_assert(BitIntZero2 == 0, "");
constexpr unsigned _BitInt(1) UBitIntZero1{};
static_assert(UBitIntZero1 == 0, "");

constexpr unsigned _BitInt(2) BI1 = 3u;
static_assert(BI1 == 3, "");


#ifdef __SIZEOF_INT128__
namespace i128 {