https://github.com/tbaederr created https://github.com/llvm/llvm-project/pull/69911
The added test case used to fail because we converted the LHS to `-1`. >From 6bae86e6d728996b92b0dfbbd62c254f1f32af9d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timm=20B=C3=A4der?= <tbae...@redhat.com> Date: Mon, 23 Oct 2023 11:43:32 +0200 Subject: [PATCH] [clang][Interp] Fix truncateCast() --- clang/lib/AST/Interp/IntegralAP.h | 36 +++++++++++++++++++++---------- clang/test/AST/Interp/intap.cpp | 3 +++ 2 files changed, 28 insertions(+), 11 deletions(-) diff --git a/clang/lib/AST/Interp/IntegralAP.h b/clang/lib/AST/Interp/IntegralAP.h index 45e5b49546270aa..98d4dae8fa4df0e 100644 --- a/clang/lib/AST/Interp/IntegralAP.h +++ b/clang/lib/AST/Interp/IntegralAP.h @@ -35,10 +35,18 @@ template <bool Signed> class IntegralAP final { 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(); @@ -81,14 +89,20 @@ template <bool Signed> class IntegralAP final { } 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); } + explicit operator int8_t() const { return truncateCast<int8_t, Signed>(V); } + explicit operator uint8_t() const { return truncateCast<uint8_t, Signed>(V); } + explicit operator int16_t() const { return truncateCast<int16_t, Signed>(V); } + explicit operator uint16_t() const { + return truncateCast<uint16_t, Signed>(V); + } + explicit operator int32_t() const { return truncateCast<int32_t, Signed>(V); } + explicit operator uint32_t() const { + return truncateCast<uint32_t, Signed>(V); + } + explicit operator int64_t() const { return truncateCast<int64_t, Signed>(V); } + explicit operator uint64_t() const { + return truncateCast<uint64_t, Signed>(V); + } template <typename T> static IntegralAP from(T Value, unsigned NumBits = 0) { assert(NumBits > 0); diff --git a/clang/test/AST/Interp/intap.cpp b/clang/test/AST/Interp/intap.cpp index 27fae1b904351ce..02a860eb0986c15 100644 --- a/clang/test/AST/Interp/intap.cpp +++ b/clang/test/AST/Interp/intap.cpp @@ -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 { _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits