[clang] e3f4fa9 - [clang][Interp] Implement inc/dec for IntegralAP (#69597)

via cfe-commits cfe-commits at lists.llvm.org
Tue Dec 12 01:44:48 PST 2023


Author: Timm Baeder
Date: 2023-12-12T10:44:43+01:00
New Revision: e3f4fa98349b85dbd7845a505a98bd331e5d2897

URL: https://github.com/llvm/llvm-project/commit/e3f4fa98349b85dbd7845a505a98bd331e5d2897
DIFF: https://github.com/llvm/llvm-project/commit/e3f4fa98349b85dbd7845a505a98bd331e5d2897.diff

LOG: [clang][Interp] Implement inc/dec for IntegralAP (#69597)

Implement `++` and `--` for arbitrary-bitwidth values.

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 9019f32e6cef2a..d5f46409d231d4 100644
--- a/clang/lib/AST/Interp/IntegralAP.h
+++ b/clang/lib/AST/Interp/IntegralAP.h
@@ -182,17 +182,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 c93ec331296647..b99422dc8f9312 100644
--- a/clang/test/AST/Interp/intap.cpp
+++ b/clang/test/AST/Interp/intap.cpp
@@ -57,9 +57,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, "");
@@ -200,4 +216,50 @@ namespace BitOps {
   static_assert((Max ^ UZero) == Max, "");
 }
 
+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