[clang] [clang][Interp] Implement IntegralAP::{div, rem} (PR #72614)

Timm Baeder via cfe-commits cfe-commits at lists.llvm.org
Fri Jan 12 00:27:54 PST 2024


https://github.com/tbaederr updated https://github.com/llvm/llvm-project/pull/72614

>From 8b657f24c900d9e123a74c76eb3c12c1d34f1a93 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= <tbaeder at redhat.com>
Date: Thu, 16 Nov 2023 18:05:17 +0100
Subject: [PATCH] [clang][Interp] Implement IntegralAP::{div, rem}

---
 clang/lib/AST/Interp/IntegralAP.h | 12 ++++++++----
 clang/test/AST/Interp/intap.cpp   | 30 ++++++++++++++++++++++++++++++
 2 files changed, 38 insertions(+), 4 deletions(-)

diff --git a/clang/lib/AST/Interp/IntegralAP.h b/clang/lib/AST/Interp/IntegralAP.h
index d5f46409d231d48..55e29caa1cd7471 100644
--- a/clang/lib/AST/Interp/IntegralAP.h
+++ b/clang/lib/AST/Interp/IntegralAP.h
@@ -204,14 +204,18 @@ template <bool Signed> class IntegralAP final {
   }
 
   static bool rem(IntegralAP A, IntegralAP B, unsigned OpBits, IntegralAP *R) {
-    // FIXME: Implement.
-    assert(false);
+    if constexpr (Signed)
+      *R = IntegralAP(A.V.srem(B.V));
+    else
+      *R = IntegralAP(A.V.urem(B.V));
     return false;
   }
 
   static bool div(IntegralAP A, IntegralAP B, unsigned OpBits, IntegralAP *R) {
-    // FIXME: Implement.
-    assert(false);
+    if constexpr (Signed)
+      *R = IntegralAP(A.V.sdiv(B.V));
+    else
+      *R = IntegralAP(A.V.udiv(B.V));
     return false;
   }
 
diff --git a/clang/test/AST/Interp/intap.cpp b/clang/test/AST/Interp/intap.cpp
index b99422dc8f93125..118dc21b67e875f 100644
--- a/clang/test/AST/Interp/intap.cpp
+++ b/clang/test/AST/Interp/intap.cpp
@@ -5,6 +5,7 @@
 
 
 using MaxBitInt = _BitInt(128);
+#define INT_MIN (~__INT_MAX__)
 
 constexpr _BitInt(2) A = 0;
 constexpr _BitInt(2) B = A + 1;
@@ -44,6 +45,35 @@ static_assert(MulA * MulB == 50, ""); // ref-error {{not an integral constant ex
 static_assert(MulA * 5 == 25, "");
 static_assert(-1 * MulB == -7, "");
 
+
+constexpr _BitInt(4) DivA = 2;
+constexpr _BitInt(2) DivB = 1;
+static_assert(DivA / DivB == 2, "");
+
+constexpr _BitInt(4) DivC = DivA / 0; // ref-error {{must be initialized by a constant expression}} \
+                                      // ref-note {{division by zero}} \
+                                      // expected-error {{must be initialized by a constant expression}} \
+                                      // expected-note {{division by zero}}
+
+constexpr _BitInt(7) RemA = 47;
+constexpr _BitInt(6) RemB = 9;
+static_assert(RemA % RemB == 2, "");
+static_assert(RemA % 0 == 1, ""); // ref-error {{not an integral constant expression}} \
+                                  // ref-note {{division by zero}} \
+                                  // expected-error {{not an integral constant expression}} \
+                                  // expected-note {{division by zero}}
+
+constexpr _BitInt(32) bottom = -1;
+constexpr _BitInt(32) top = INT_MIN;
+constexpr _BitInt(32) nope = top / bottom;  // ref-error {{must be initialized by a constant expression}} \
+                                            // ref-note {{value 2147483648 is outside the range}} \
+                                            // expected-error {{must be initialized by a constant expression}} \
+                                            // expected-note {{value 2147483648 is outside the range}}
+constexpr _BitInt(32) noooo = top % bottom; // ref-error {{must be initialized by a constant expression}} \
+                                            // ref-note {{value 2147483648 is outside the range}} \
+                                            // expected-error {{must be initialized by a constant expression}} \
+                                            // expected-note {{value 2147483648 is outside the range}}
+
 namespace APCast {
   constexpr _BitInt(10) A = 1;
   constexpr _BitInt(11) B = A;



More information about the cfe-commits mailing list