[clang] [clang][Interp] Implement inc/dec for IntegralAP (PR #69597)
Timm Baeder via cfe-commits
cfe-commits at lists.llvm.org
Thu Nov 9 03:17:55 PST 2023
https://github.com/tbaederr updated https://github.com/llvm/llvm-project/pull/69597
>From be120871fa8486ce9dd6cabb0a0b27d8371896b8 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= <tbaeder at redhat.com>
Date: Wed, 18 Oct 2023 15:36:13 +0200
Subject: [PATCH] [clang][Interp] Implement inc/dec for IntegralAP
---
clang/lib/AST/Interp/IntegralAP.h | 12 ++---
clang/test/AST/Interp/intap.cpp | 81 ++++++++++++++++++++++++-------
2 files changed, 68 insertions(+), 25 deletions(-)
diff --git a/clang/lib/AST/Interp/IntegralAP.h b/clang/lib/AST/Interp/IntegralAP.h
index 88de1f1392e6813..82da79a55b05312 100644
--- a/clang/lib/AST/Interp/IntegralAP.h
+++ b/clang/lib/AST/Interp/IntegralAP.h
@@ -177,17 +177,13 @@ template <bool Signed> class IntegralAP final {
}
static bool increment(IntegralAP A, IntegralAP *R) {
- // FIXME: Implement.
- assert(false);
- *R = IntegralAP(A.V - 1);
- return false;
+ IntegralAP<Signed> One(1, A.bitWidth());
+ return add(A, One, A.bitWidth() + 1, R);
}
static bool decrement(IntegralAP A, IntegralAP *R) {
- // FIXME: Implement.
- assert(false);
- *R = IntegralAP(A.V - 1);
- return false;
+ IntegralAP<Signed> One(1, A.bitWidth());
+ return sub(A, One, A.bitWidth() + 1, R);
}
static bool add(IntegralAP A, IntegralAP B, unsigned OpBits, IntegralAP *R) {
diff --git a/clang/test/AST/Interp/intap.cpp b/clang/test/AST/Interp/intap.cpp
index 34c8d0565082994..73c795732ff1055 100644
--- a/clang/test/AST/Interp/intap.cpp
+++ b/clang/test/AST/Interp/intap.cpp
@@ -43,9 +43,25 @@ namespace APCast {
}
#ifdef __SIZEOF_INT128__
+typedef __int128 int128_t;
+typedef unsigned __int128 uint128_t;
+static const __uint128_t UINT128_MAX =__uint128_t(__int128_t(-1L));
+static_assert(UINT128_MAX == -1, "");
+static_assert(UINT128_MAX == 1, ""); // expected-error {{static assertion failed}} \
+ // expected-note {{'340282366920938463463374607431768211455 == 1'}} \
+ // ref-error {{static assertion failed}} \
+ // ref-note {{'340282366920938463463374607431768211455 == 1'}}
+
+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;
+
namespace i128 {
- typedef __int128 int128_t;
- typedef unsigned __int128 uint128_t;
+
constexpr int128_t I128_1 = 12;
static_assert(I128_1 == 12, "");
static_assert(I128_1 != 10, "");
@@ -54,21 +70,6 @@ namespace i128 {
// expected-note{{evaluates to}} \
// ref-note{{evaluates to}}
- static const __uint128_t UINT128_MAX =__uint128_t(__int128_t(-1L));
- static_assert(UINT128_MAX == -1, "");
- static_assert(UINT128_MAX == 1, ""); // expected-error {{static assertion failed}} \
- // expected-note {{'340282366920938463463374607431768211455 == 1'}} \
- // ref-error {{static assertion failed}} \
- // ref-note {{'340282366920938463463374607431768211455 == 1'}}
-
- 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 {{value 170141183460469231731687303715884105728 is outside the range}} \
// ref-error {{must be initialized by a constant expression}} \
@@ -157,4 +158,50 @@ namespace Bitfields {
// expected-warning {{changes value from 100 to 0}}
}
+namespace IncDec {
+#if __cplusplus >= 201402L
+ constexpr int128_t maxPlus1(bool Pre) {
+ int128_t a = INT128_MAX;
+
+ if (Pre)
+ ++a; // ref-note {{value 170141183460469231731687303715884105728 is outside the range}} \
+ // expected-note {{value 170141183460469231731687303715884105728 is outside the range}}
+ else
+ a++; // ref-note {{value 170141183460469231731687303715884105728 is outside the range}} \
+ // expected-note {{value 170141183460469231731687303715884105728 is outside the range}}
+ return a;
+ }
+ static_assert(maxPlus1(true) == 0, ""); // ref-error {{not an integral constant expression}} \
+ // ref-note {{in call to}} \
+ // expected-error {{not an integral constant expression}} \
+ // expected-note {{in call to}}
+ static_assert(maxPlus1(false) == 0, ""); // ref-error {{not an integral constant expression}} \
+ // ref-note {{in call to}} \
+ // expected-error {{not an integral constant expression}} \
+ // expected-note {{in call to}}
+
+ constexpr int128_t inc1(bool Pre) {
+ int128_t A = 0;
+ if (Pre)
+ ++A;
+ else
+ A++;
+ return A;
+ }
+ static_assert(inc1(true) == 1, "");
+ static_assert(inc1(false) == 1, "");
+
+ constexpr int128_t dec1(bool Pre) {
+ int128_t A = 2;
+ if (Pre)
+ --A;
+ else
+ A--;
+ return A;
+ }
+ static_assert(dec1(true) == 1, "");
+ static_assert(dec1(false) == 1, "");
+#endif
+}
+
#endif
More information about the cfe-commits
mailing list