Skip to content

Commit 8feb083

Browse files
authored
[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.
1 parent b7b5907 commit 8feb083

File tree

2 files changed

+17
-4
lines changed

2 files changed

+17
-4
lines changed

clang/lib/AST/Interp/IntegralAP.h

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -119,8 +119,16 @@ template <bool Signed> class IntegralAP final {
119119

120120
constexpr unsigned bitWidth() const { return V.getBitWidth(); }
121121

122-
APSInt toAPSInt(unsigned Bits = 0) const { return APSInt(V, !Signed); }
123-
APValue toAPValue() const { return APValue(APSInt(V, !Signed)); }
122+
APSInt toAPSInt(unsigned Bits = 0) const {
123+
if (Bits == 0)
124+
Bits = bitWidth();
125+
126+
if constexpr (Signed)
127+
return APSInt(V.sext(Bits), !Signed);
128+
else
129+
return APSInt(V.zext(Bits), !Signed);
130+
}
131+
APValue toAPValue() const { return APValue(toAPSInt()); }
124132

125133
bool isZero() const { return V.isZero(); }
126134
bool isPositive() const { return V.isNonNegative(); }

clang/test/AST/Interp/intap.cpp

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,11 +63,16 @@ namespace i128 {
6363

6464
static const __int128_t INT128_MAX = UINT128_MAX >> (__int128_t)1;
6565
static_assert(INT128_MAX != 0, "");
66+
static_assert(INT128_MAX == 0, ""); // expected-error {{failed}} \
67+
// expected-note {{evaluates to '170141183460469231731687303715884105727 == 0'}} \
68+
// ref-error {{failed}} \
69+
// ref-note {{evaluates to '170141183460469231731687303715884105727 == 0'}}
70+
6671
static const __int128_t INT128_MIN = -INT128_MAX - 1;
6772
constexpr __int128 A = INT128_MAX + 1; // expected-error {{must be initialized by a constant expression}} \
68-
// expected-note {{outside the range}} \
73+
// expected-note {{value 170141183460469231731687303715884105728 is outside the range}} \
6974
// ref-error {{must be initialized by a constant expression}} \
70-
// ref-note {{outside the range}}
75+
// ref-note {{value 170141183460469231731687303715884105728 is outside the range}}
7176
constexpr int128_t Two = (int128_t)1 << 1ul;
7277
static_assert(Two == 2, "");
7378
static_assert(Two, "");

0 commit comments

Comments
 (0)