[clang] 8feb083 - [clang][Interp] Consider bit width in IntegralAP::toAPSInt() (#71646)
via cfe-commits
cfe-commits at lists.llvm.org
Wed Nov 8 22:46:59 PST 2023
Author: Timm Baeder
Date: 2023-11-09T07:46:55+01:00
New Revision: 8feb0830cb5c731a34dc74ff6f0c1c4702bc4734
URL: https://github.com/llvm/llvm-project/commit/8feb0830cb5c731a34dc74ff6f0c1c4702bc4734
DIFF: https://github.com/llvm/llvm-project/commit/8feb0830cb5c731a34dc74ff6f0c1c4702bc4734.diff
LOG: [clang][Interp] Consider bit width in IntegralAP::toAPSInt() (#71646)
In `Interp.h`, when a add/sub/mul fails, we call this code and expect to
get an `APSInt` back that can handle more than the current bitwidth of
the type.
Added:
Modified:
clang/lib/AST/Interp/IntegralAP.h
clang/test/AST/Interp/intap.cpp
Removed:
################################################################################
diff --git a/clang/lib/AST/Interp/IntegralAP.h b/clang/lib/AST/Interp/IntegralAP.h
index b674082d9ea5812..88de1f1392e6813 100644
--- a/clang/lib/AST/Interp/IntegralAP.h
+++ b/clang/lib/AST/Interp/IntegralAP.h
@@ -119,8 +119,16 @@ template <bool Signed> class IntegralAP final {
constexpr unsigned bitWidth() const { return V.getBitWidth(); }
- APSInt toAPSInt(unsigned Bits = 0) const { return APSInt(V, !Signed); }
- APValue toAPValue() const { return APValue(APSInt(V, !Signed)); }
+ APSInt toAPSInt(unsigned Bits = 0) const {
+ if (Bits == 0)
+ Bits = bitWidth();
+
+ if constexpr (Signed)
+ return APSInt(V.sext(Bits), !Signed);
+ else
+ return APSInt(V.zext(Bits), !Signed);
+ }
+ APValue toAPValue() const { return APValue(toAPSInt()); }
bool isZero() const { return V.isZero(); }
bool isPositive() const { return V.isNonNegative(); }
diff --git a/clang/test/AST/Interp/intap.cpp b/clang/test/AST/Interp/intap.cpp
index 5f08b76a565c25a..34c8d0565082994 100644
--- a/clang/test/AST/Interp/intap.cpp
+++ b/clang/test/AST/Interp/intap.cpp
@@ -63,11 +63,16 @@ namespace i128 {
static const __int128_t INT128_MAX = UINT128_MAX >> (__int128_t)1;
static_assert(INT128_MAX != 0, "");
+ static_assert(INT128_MAX == 0, ""); // expected-error {{failed}} \
+ // expected-note {{evaluates to '170141183460469231731687303715884105727 == 0'}} \
+ // ref-error {{failed}} \
+ // ref-note {{evaluates to '170141183460469231731687303715884105727 == 0'}}
+
static const __int128_t INT128_MIN = -INT128_MAX - 1;
constexpr __int128 A = INT128_MAX + 1; // expected-error {{must be initialized by a constant expression}} \
- // expected-note {{outside the range}} \
+ // expected-note {{value 170141183460469231731687303715884105728 is outside the range}} \
// ref-error {{must be initialized by a constant expression}} \
- // ref-note {{outside the range}}
+ // ref-note {{value 170141183460469231731687303715884105728 is outside the range}}
constexpr int128_t Two = (int128_t)1 << 1ul;
static_assert(Two == 2, "");
static_assert(Two, "");
More information about the cfe-commits
mailing list