Skip to content

Commit

Permalink
[clang][Interp] Implement IntegralAP::mul() (#72491)
Browse files Browse the repository at this point in the history
  • Loading branch information
tbaederr committed Nov 16, 2023
1 parent 545f4d9 commit 4cf996d
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 7 deletions.
12 changes: 5 additions & 7 deletions clang/lib/AST/Interp/IntegralAP.h
Original file line number Diff line number Diff line change
Expand Up @@ -191,17 +191,15 @@ template <bool Signed> class IntegralAP final {
}

static bool add(IntegralAP A, IntegralAP B, unsigned OpBits, IntegralAP *R) {
return CheckAddSubUB<std::plus>(A, B, OpBits, R);
return CheckAddSubMulUB<std::plus>(A, B, OpBits, R);
}

static bool sub(IntegralAP A, IntegralAP B, unsigned OpBits, IntegralAP *R) {
return CheckAddSubUB<std::minus>(A, B, OpBits, R);
return CheckAddSubMulUB<std::minus>(A, B, OpBits, R);
}

static bool mul(IntegralAP A, IntegralAP B, unsigned OpBits, IntegralAP *R) {
// FIXME: Implement.
assert(false);
return false;
return CheckAddSubMulUB<std::multiplies>(A, B, OpBits, R);
}

static bool rem(IntegralAP A, IntegralAP B, unsigned OpBits, IntegralAP *R) {
Expand Down Expand Up @@ -262,8 +260,8 @@ template <bool Signed> class IntegralAP final {

private:
template <template <typename T> class Op>
static bool CheckAddSubUB(const IntegralAP &A, const IntegralAP &B,
unsigned BitWidth, IntegralAP *R) {
static bool CheckAddSubMulUB(const IntegralAP &A, const IntegralAP &B,
unsigned BitWidth, IntegralAP *R) {
if constexpr (!Signed) {
R->V = Op<APInt>{}(A.V, B.V);
return false;
Expand Down
16 changes: 16 additions & 0 deletions clang/test/AST/Interp/intap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,15 @@ static_assert(UBitIntZero1 == 0, "");
constexpr unsigned _BitInt(2) BI1 = 3u;
static_assert(BI1 == 3, "");

constexpr _BitInt(4) MulA = 5;
constexpr _BitInt(4) MulB = 7;
static_assert(MulA * MulB == 50, ""); // ref-error {{not an integral constant expression}} \
// ref-note {{value 35 is outside the range of representable values of type '_BitInt(4)'}} \
// expected-error {{not an integral constant expression}} \
// expected-note {{value 35 is outside the range of representable values of type '_BitInt(4)'}}
static_assert(MulA * 5 == 25, "");
static_assert(-1 * MulB == -7, "");

namespace APCast {
constexpr _BitInt(10) A = 1;
constexpr _BitInt(11) B = A;
Expand Down Expand Up @@ -66,13 +75,20 @@ namespace i128 {
// ref-error {{static assertion failed}} \
// ref-note {{'340282366920938463463374607431768211455 == 1'}}

constexpr uint128_t TooMuch = UINT128_MAX * 2;

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'}}

constexpr int128_t TooMuch2 = INT128_MAX * INT128_MAX; // ref-error {{must be initialized by a constant expression}} \
// ref-note {{value 28948022309329048855892746252171976962977213799489202546401021394546514198529 is outside the range of representable}} \
// expected-error {{must be initialized by a constant expression}} \
// expected-note {{value 28948022309329048855892746252171976962977213799489202546401021394546514198529 is outside the range of representable}}

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 {{value 170141183460469231731687303715884105728 is outside the range}} \
Expand Down

0 comments on commit 4cf996d

Please sign in to comment.