[clang] [clang][Interp] Fix value truncation when casting int128 to smaller size (PR #67961)

2023-10-02 Thread Timm Baeder via cfe-commits

https://github.com/tbaederr closed 
https://github.com/llvm/llvm-project/pull/67961
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][Interp] Fix value truncation when casting int128 to smaller size (PR #67961)

2023-10-02 Thread Erich Keane via cfe-commits

https://github.com/erichkeane approved this pull request.


https://github.com/llvm/llvm-project/pull/67961
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][Interp] Fix value truncation when casting int128 to smaller size (PR #67961)

2023-10-02 Thread Timm Baeder via cfe-commits

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

>From 377e0b069ff0d68ff4a4cdd690b62e555bdf8d8a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= 
Date: Mon, 2 Oct 2023 10:46:22 +0200
Subject: [PATCH] [clang][Interp] Fix value truncation when casting int128 to
 smaller size

---
 clang/lib/AST/Interp/IntegralAP.h  | 22 ++
 clang/test/AST/Interp/literals.cpp | 10 +-
 2 files changed, 23 insertions(+), 9 deletions(-)

diff --git a/clang/lib/AST/Interp/IntegralAP.h 
b/clang/lib/AST/Interp/IntegralAP.h
index 42f44354cbd2599..0876d7fae958a54 100644
--- a/clang/lib/AST/Interp/IntegralAP.h
+++ b/clang/lib/AST/Interp/IntegralAP.h
@@ -32,6 +32,12 @@ template  class Integral;
 class Boolean;
 
 template  class IntegralAP final {
+private:
+  template  static T truncateCast(const APSInt ) {
+return std::is_signed_v ? V.trunc(sizeof(T) * 8).getSExtValue()
+   : V.trunc(sizeof(T) * 8).getZExtValue();
+  }
+
 public:
   APSInt V;
 
@@ -55,14 +61,14 @@ template  class IntegralAP final {
   bool operator<=(IntegralAP RHS) const { return V <= RHS.V; }
 
   explicit operator bool() const { return !V.isZero(); }
-  explicit operator int8_t() const { return V.getSExtValue(); }
-  explicit operator uint8_t() const { return V.getZExtValue(); }
-  explicit operator int16_t() const { return V.getSExtValue(); }
-  explicit operator uint16_t() const { return V.getZExtValue(); }
-  explicit operator int32_t() const { return V.getSExtValue(); }
-  explicit operator uint32_t() const { return V.getZExtValue(); }
-  explicit operator int64_t() const { return V.getSExtValue(); }
-  explicit operator uint64_t() const { return V.getZExtValue(); }
+  explicit operator int8_t() const { return truncateCast(V); }
+  explicit operator uint8_t() const { return truncateCast(V); }
+  explicit operator int16_t() const { return truncateCast(V); }
+  explicit operator uint16_t() const { return truncateCast(V); }
+  explicit operator int32_t() const { return truncateCast(V); }
+  explicit operator uint32_t() const { return truncateCast(V); }
+  explicit operator int64_t() const { return truncateCast(V); }
+  explicit operator uint64_t() const { return truncateCast(V); }
 
   template  static IntegralAP from(T Value, unsigned NumBits = 0) {
 assert(NumBits > 0);
diff --git a/clang/test/AST/Interp/literals.cpp 
b/clang/test/AST/Interp/literals.cpp
index 00182ba4ab1d918..00875bcf44dc8e6 100644
--- a/clang/test/AST/Interp/literals.cpp
+++ b/clang/test/AST/Interp/literals.cpp
@@ -53,7 +53,7 @@ namespace i128 {
   static_assert(Two == 2, "");
 
   constexpr uint128_t AllOnes = ~static_cast(0);
-  static_assert(AllOnes == static_cast(-1), "");
+  static_assert(AllOnes == UINT128_MAX, "");
 
 #if __cplusplus >= 201402L
   template 
@@ -70,6 +70,14 @@ namespace i128 {
   static_assert(CastFrom(12) == 12, "");
   static_assert(CastFrom(12) == 12, "");
 
+  static_assert(CastFrom(AllOnes) == -1, "");
+  static_assert(CastFrom(AllOnes) == 0xFF, "");
+  static_assert(CastFrom(AllOnes) == -1, "");
+  static_assert(CastFrom(AllOnes) == 0x, "");
+  static_assert(CastFrom(AllOnes) == -1, "");
+  static_assert(CastFrom(AllOnes) == -1, "");
+  static_assert(CastFrom(AllOnes) == AllOnes, "");
+
   template 
   constexpr __int128 CastTo(T A) {
 int128_t B = (int128_t)A;

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][Interp] Fix value truncation when casting int128 to smaller size (PR #67961)

2023-10-02 Thread Timm Baeder via cfe-commits
Timm =?utf-8?q?Bäder?= 
Message-ID:
In-Reply-To: 


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

>From d7ee51b3736ee65279f07bb0f4d5ccc31911cfda Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= 
Date: Sun, 1 Oct 2023 19:57:03 +0200
Subject: [PATCH 1/2] [clang][Interp] Implement IntegralAP::comp

---
 clang/lib/AST/Interp/IntegralAP.h  | 1 -
 clang/test/AST/Interp/literals.cpp | 3 +++
 2 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/clang/lib/AST/Interp/IntegralAP.h 
b/clang/lib/AST/Interp/IntegralAP.h
index a9e34a5b237a195..42f44354cbd2599 100644
--- a/clang/lib/AST/Interp/IntegralAP.h
+++ b/clang/lib/AST/Interp/IntegralAP.h
@@ -210,7 +210,6 @@ template  class IntegralAP final {
   }
 
   static bool comp(IntegralAP A, IntegralAP *R) {
-assert(false);
 *R = IntegralAP(~A.V);
 return false;
   }
diff --git a/clang/test/AST/Interp/literals.cpp 
b/clang/test/AST/Interp/literals.cpp
index eca0e4c2cbd26f1..00182ba4ab1d918 100644
--- a/clang/test/AST/Interp/literals.cpp
+++ b/clang/test/AST/Interp/literals.cpp
@@ -52,6 +52,9 @@ namespace i128 {
   constexpr int128_t Two = (int128_t)1 << 1ul;
   static_assert(Two == 2, "");
 
+  constexpr uint128_t AllOnes = ~static_cast(0);
+  static_assert(AllOnes == static_cast(-1), "");
+
 #if __cplusplus >= 201402L
   template 
   constexpr T CastFrom(__int128_t A) {

>From 7f551e9f971f3a9a74efda169e5765657ba3c8fe Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= 
Date: Mon, 2 Oct 2023 10:46:22 +0200
Subject: [PATCH 2/2] [clang][Interp] Fix value truncation when casting int128
 to smaller size

---
 clang/lib/AST/Interp/IntegralAP.h  | 22 ++
 clang/test/AST/Interp/literals.cpp | 10 +-
 2 files changed, 23 insertions(+), 9 deletions(-)

diff --git a/clang/lib/AST/Interp/IntegralAP.h 
b/clang/lib/AST/Interp/IntegralAP.h
index 42f44354cbd2599..0876d7fae958a54 100644
--- a/clang/lib/AST/Interp/IntegralAP.h
+++ b/clang/lib/AST/Interp/IntegralAP.h
@@ -32,6 +32,12 @@ template  class Integral;
 class Boolean;
 
 template  class IntegralAP final {
+private:
+  template  static T truncateCast(const APSInt ) {
+return std::is_signed_v ? V.trunc(sizeof(T) * 8).getSExtValue()
+   : V.trunc(sizeof(T) * 8).getZExtValue();
+  }
+
 public:
   APSInt V;
 
@@ -55,14 +61,14 @@ template  class IntegralAP final {
   bool operator<=(IntegralAP RHS) const { return V <= RHS.V; }
 
   explicit operator bool() const { return !V.isZero(); }
-  explicit operator int8_t() const { return V.getSExtValue(); }
-  explicit operator uint8_t() const { return V.getZExtValue(); }
-  explicit operator int16_t() const { return V.getSExtValue(); }
-  explicit operator uint16_t() const { return V.getZExtValue(); }
-  explicit operator int32_t() const { return V.getSExtValue(); }
-  explicit operator uint32_t() const { return V.getZExtValue(); }
-  explicit operator int64_t() const { return V.getSExtValue(); }
-  explicit operator uint64_t() const { return V.getZExtValue(); }
+  explicit operator int8_t() const { return truncateCast(V); }
+  explicit operator uint8_t() const { return truncateCast(V); }
+  explicit operator int16_t() const { return truncateCast(V); }
+  explicit operator uint16_t() const { return truncateCast(V); }
+  explicit operator int32_t() const { return truncateCast(V); }
+  explicit operator uint32_t() const { return truncateCast(V); }
+  explicit operator int64_t() const { return truncateCast(V); }
+  explicit operator uint64_t() const { return truncateCast(V); }
 
   template  static IntegralAP from(T Value, unsigned NumBits = 0) {
 assert(NumBits > 0);
diff --git a/clang/test/AST/Interp/literals.cpp 
b/clang/test/AST/Interp/literals.cpp
index 00182ba4ab1d918..00875bcf44dc8e6 100644
--- a/clang/test/AST/Interp/literals.cpp
+++ b/clang/test/AST/Interp/literals.cpp
@@ -53,7 +53,7 @@ namespace i128 {
   static_assert(Two == 2, "");
 
   constexpr uint128_t AllOnes = ~static_cast(0);
-  static_assert(AllOnes == static_cast(-1), "");
+  static_assert(AllOnes == UINT128_MAX, "");
 
 #if __cplusplus >= 201402L
   template 
@@ -70,6 +70,14 @@ namespace i128 {
   static_assert(CastFrom(12) == 12, "");
   static_assert(CastFrom(12) == 12, "");
 
+  static_assert(CastFrom(AllOnes) == -1, "");
+  static_assert(CastFrom(AllOnes) == 0xFF, "");
+  static_assert(CastFrom(AllOnes) == -1, "");
+  static_assert(CastFrom(AllOnes) == 0x, "");
+  static_assert(CastFrom(AllOnes) == -1, "");
+  static_assert(CastFrom(AllOnes) == -1, "");
+  static_assert(CastFrom(AllOnes) == AllOnes, "");
+
   template 
   constexpr __int128 CastTo(T A) {
 int128_t B = (int128_t)A;

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][Interp] Fix value truncation when casting int128 to smaller size (PR #67961)

2023-10-02 Thread via cfe-commits
Timm =?utf-8?q?Bäder?= 
Message-ID:
In-Reply-To: 


github-actions[bot] wrote:




:warning: C/C++ code formatter, clang-format found issues in your code. 
:warning:



You can test this locally with the following command:


``bash
git-clang-format --diff 1a3a1d9674df00451ab6f7153b78d5f60abcd3c9 
3c8924be41121056b60b0aa4d2a3de43dd2db9e3 -- clang/lib/AST/Interp/IntegralAP.h 
clang/test/AST/Interp/literals.cpp
``





View the diff from clang-format here.


``diff
diff --git a/clang/lib/AST/Interp/IntegralAP.h 
b/clang/lib/AST/Interp/IntegralAP.h
index ca45c7e243e2..1f49077608f4 100644
--- a/clang/lib/AST/Interp/IntegralAP.h
+++ b/clang/lib/AST/Interp/IntegralAP.h
@@ -33,7 +33,6 @@ class Boolean;
 
 template  class IntegralAP final {
 private:
-
   template  static T truncateCast(const APSInt ) {
 return std::is_signed_v ? V.trunc(sizeof(T) * 8).getSExtValue()
: V.trunc(sizeof(T) * 8).getZExtValue();

``




https://github.com/llvm/llvm-project/pull/67961
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][Interp] Fix value truncation when casting int128 to smaller size (PR #67961)

2023-10-02 Thread Erich Keane via cfe-commits
Timm =?utf-8?q?B=C3=A4der?= 
Message-ID:
In-Reply-To: 


https://github.com/erichkeane approved this pull request.


https://github.com/llvm/llvm-project/pull/67961
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][Interp] Fix value truncation when casting int128 to smaller size (PR #67961)

2023-10-02 Thread Timm Baeder via cfe-commits
Timm =?utf-8?q?Bäder?= 
Message-ID:
In-Reply-To: 


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

>From 80bd890c332654458014c4acc20709b9cbb6eb90 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= 
Date: Sun, 1 Oct 2023 19:57:03 +0200
Subject: [PATCH 1/2] [clang][Interp] Implement IntegralAP::comp

---
 clang/lib/AST/Interp/IntegralAP.h  | 1 -
 clang/test/AST/Interp/literals.cpp | 3 +++
 2 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/clang/lib/AST/Interp/IntegralAP.h 
b/clang/lib/AST/Interp/IntegralAP.h
index b2b367f30c238fe..b29aac2a73e3243 100644
--- a/clang/lib/AST/Interp/IntegralAP.h
+++ b/clang/lib/AST/Interp/IntegralAP.h
@@ -210,7 +210,6 @@ template  class IntegralAP final {
   }
 
   static bool comp(IntegralAP A, IntegralAP *R) {
-assert(false);
 *R = IntegralAP(~A.V);
 return false;
   }
diff --git a/clang/test/AST/Interp/literals.cpp 
b/clang/test/AST/Interp/literals.cpp
index eca0e4c2cbd26f1..00182ba4ab1d918 100644
--- a/clang/test/AST/Interp/literals.cpp
+++ b/clang/test/AST/Interp/literals.cpp
@@ -52,6 +52,9 @@ namespace i128 {
   constexpr int128_t Two = (int128_t)1 << 1ul;
   static_assert(Two == 2, "");
 
+  constexpr uint128_t AllOnes = ~static_cast(0);
+  static_assert(AllOnes == static_cast(-1), "");
+
 #if __cplusplus >= 201402L
   template 
   constexpr T CastFrom(__int128_t A) {

>From 3c8924be41121056b60b0aa4d2a3de43dd2db9e3 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= 
Date: Mon, 2 Oct 2023 10:46:22 +0200
Subject: [PATCH 2/2] [clang][Interp] Fix value truncation when casting int128
 to smaller size

---
 clang/lib/AST/Interp/IntegralAP.h  | 23 +++
 clang/test/AST/Interp/literals.cpp | 10 +-
 2 files changed, 24 insertions(+), 9 deletions(-)

diff --git a/clang/lib/AST/Interp/IntegralAP.h 
b/clang/lib/AST/Interp/IntegralAP.h
index b29aac2a73e3243..ca45c7e243e20ba 100644
--- a/clang/lib/AST/Interp/IntegralAP.h
+++ b/clang/lib/AST/Interp/IntegralAP.h
@@ -32,6 +32,13 @@ template  class Integral;
 class Boolean;
 
 template  class IntegralAP final {
+private:
+
+  template  static T truncateCast(const APSInt ) {
+return std::is_signed_v ? V.trunc(sizeof(T) * 8).getSExtValue()
+   : V.trunc(sizeof(T) * 8).getZExtValue();
+  }
+
 public:
   APSInt V;
 
@@ -55,14 +62,14 @@ template  class IntegralAP final {
   bool operator<=(IntegralAP RHS) const { return V <= RHS.V; }
 
   explicit operator bool() const { return !V.isZero(); }
-  explicit operator int8_t() const { return V.getSExtValue(); }
-  explicit operator uint8_t() const { return V.getZExtValue(); }
-  explicit operator int16_t() const { return V.getSExtValue(); }
-  explicit operator uint16_t() const { return V.getZExtValue(); }
-  explicit operator int32_t() const { return V.getSExtValue(); }
-  explicit operator uint32_t() const { return V.getZExtValue(); }
-  explicit operator int64_t() const { return V.getSExtValue(); }
-  explicit operator uint64_t() const { return V.getZExtValue(); }
+  explicit operator int8_t() const { return truncateCast(V); }
+  explicit operator uint8_t() const { return truncateCast(V); }
+  explicit operator int16_t() const { return truncateCast(V); }
+  explicit operator uint16_t() const { return truncateCast(V); }
+  explicit operator int32_t() const { return truncateCast(V); }
+  explicit operator uint32_t() const { return truncateCast(V); }
+  explicit operator int64_t() const { return truncateCast(V); }
+  explicit operator uint64_t() const { return truncateCast(V); }
 
   template  static IntegralAP from(T Value, unsigned NumBits = 0) {
 assert(NumBits > 0);
diff --git a/clang/test/AST/Interp/literals.cpp 
b/clang/test/AST/Interp/literals.cpp
index 00182ba4ab1d918..00875bcf44dc8e6 100644
--- a/clang/test/AST/Interp/literals.cpp
+++ b/clang/test/AST/Interp/literals.cpp
@@ -53,7 +53,7 @@ namespace i128 {
   static_assert(Two == 2, "");
 
   constexpr uint128_t AllOnes = ~static_cast(0);
-  static_assert(AllOnes == static_cast(-1), "");
+  static_assert(AllOnes == UINT128_MAX, "");
 
 #if __cplusplus >= 201402L
   template 
@@ -70,6 +70,14 @@ namespace i128 {
   static_assert(CastFrom(12) == 12, "");
   static_assert(CastFrom(12) == 12, "");
 
+  static_assert(CastFrom(AllOnes) == -1, "");
+  static_assert(CastFrom(AllOnes) == 0xFF, "");
+  static_assert(CastFrom(AllOnes) == -1, "");
+  static_assert(CastFrom(AllOnes) == 0x, "");
+  static_assert(CastFrom(AllOnes) == -1, "");
+  static_assert(CastFrom(AllOnes) == -1, "");
+  static_assert(CastFrom(AllOnes) == AllOnes, "");
+
   template 
   constexpr __int128 CastTo(T A) {
 int128_t B = (int128_t)A;

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][Interp] Fix value truncation when casting int128 to smaller size (PR #67961)

2023-10-02 Thread Erich Keane via cfe-commits
Timm =?utf-8?q?Bäder?= 
Message-ID:
In-Reply-To: 



@@ -249,6 +248,11 @@ template  class IntegralAP final {
 R->V = A.V - B.V;
 return false; // Success!
   }
+

erichkeane wrote:

Is this template forward declared?  Either way, I think as none of the calls 
are dependent, this ends up being UB (As the lookup 'changes' between the 
declaration and the call).

All that to say: I think you just have to move this definition above its uses.

https://github.com/llvm/llvm-project/pull/67961
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][Interp] Fix value truncation when casting int128 to smaller size (PR #67961)

2023-10-02 Thread Timm Baeder via cfe-commits
Timm =?utf-8?q?Bäder?= 
Message-ID:
In-Reply-To: 


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

>From 80bd890c332654458014c4acc20709b9cbb6eb90 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= 
Date: Sun, 1 Oct 2023 19:57:03 +0200
Subject: [PATCH 1/2] [clang][Interp] Implement IntegralAP::comp

---
 clang/lib/AST/Interp/IntegralAP.h  | 1 -
 clang/test/AST/Interp/literals.cpp | 3 +++
 2 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/clang/lib/AST/Interp/IntegralAP.h 
b/clang/lib/AST/Interp/IntegralAP.h
index b2b367f30c238fe..b29aac2a73e3243 100644
--- a/clang/lib/AST/Interp/IntegralAP.h
+++ b/clang/lib/AST/Interp/IntegralAP.h
@@ -210,7 +210,6 @@ template  class IntegralAP final {
   }
 
   static bool comp(IntegralAP A, IntegralAP *R) {
-assert(false);
 *R = IntegralAP(~A.V);
 return false;
   }
diff --git a/clang/test/AST/Interp/literals.cpp 
b/clang/test/AST/Interp/literals.cpp
index eca0e4c2cbd26f1..00182ba4ab1d918 100644
--- a/clang/test/AST/Interp/literals.cpp
+++ b/clang/test/AST/Interp/literals.cpp
@@ -52,6 +52,9 @@ namespace i128 {
   constexpr int128_t Two = (int128_t)1 << 1ul;
   static_assert(Two == 2, "");
 
+  constexpr uint128_t AllOnes = ~static_cast(0);
+  static_assert(AllOnes == static_cast(-1), "");
+
 #if __cplusplus >= 201402L
   template 
   constexpr T CastFrom(__int128_t A) {

>From c39f0d9b69d00c08be93e5843efeb185fc292741 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= 
Date: Mon, 2 Oct 2023 10:46:22 +0200
Subject: [PATCH 2/2] [clang][Interp] Fix value truncation when casting int128
 to smaller size

---
 clang/lib/AST/Interp/IntegralAP.h  | 21 +
 clang/test/AST/Interp/literals.cpp | 10 +-
 2 files changed, 22 insertions(+), 9 deletions(-)

diff --git a/clang/lib/AST/Interp/IntegralAP.h 
b/clang/lib/AST/Interp/IntegralAP.h
index b29aac2a73e3243..f67b15dbc9b31ac 100644
--- a/clang/lib/AST/Interp/IntegralAP.h
+++ b/clang/lib/AST/Interp/IntegralAP.h
@@ -55,14 +55,14 @@ template  class IntegralAP final {
   bool operator<=(IntegralAP RHS) const { return V <= RHS.V; }
 
   explicit operator bool() const { return !V.isZero(); }
-  explicit operator int8_t() const { return V.getSExtValue(); }
-  explicit operator uint8_t() const { return V.getZExtValue(); }
-  explicit operator int16_t() const { return V.getSExtValue(); }
-  explicit operator uint16_t() const { return V.getZExtValue(); }
-  explicit operator int32_t() const { return V.getSExtValue(); }
-  explicit operator uint32_t() const { return V.getZExtValue(); }
-  explicit operator int64_t() const { return V.getSExtValue(); }
-  explicit operator uint64_t() const { return V.getZExtValue(); }
+  explicit operator int8_t() const { return truncateCast(V); }
+  explicit operator uint8_t() const { return truncateCast(V); }
+  explicit operator int16_t() const { return truncateCast(V); }
+  explicit operator uint16_t() const { return truncateCast(V); }
+  explicit operator int32_t() const { return truncateCast(V); }
+  explicit operator uint32_t() const { return truncateCast(V); }
+  explicit operator int64_t() const { return truncateCast(V); }
+  explicit operator uint64_t() const { return truncateCast(V); }
 
   template  static IntegralAP from(T Value, unsigned NumBits = 0) {
 assert(NumBits > 0);
@@ -248,6 +248,11 @@ template  class IntegralAP final {
 R->V = A.V - B.V;
 return false; // Success!
   }
+
+  template  static T truncateCast(const APSInt ) {
+return std::is_signed_v ? V.trunc(sizeof(T) * 8).getSExtValue()
+   : V.trunc(sizeof(T) * 8).getZExtValue();
+  }
 };
 
 template 
diff --git a/clang/test/AST/Interp/literals.cpp 
b/clang/test/AST/Interp/literals.cpp
index 00182ba4ab1d918..00875bcf44dc8e6 100644
--- a/clang/test/AST/Interp/literals.cpp
+++ b/clang/test/AST/Interp/literals.cpp
@@ -53,7 +53,7 @@ namespace i128 {
   static_assert(Two == 2, "");
 
   constexpr uint128_t AllOnes = ~static_cast(0);
-  static_assert(AllOnes == static_cast(-1), "");
+  static_assert(AllOnes == UINT128_MAX, "");
 
 #if __cplusplus >= 201402L
   template 
@@ -70,6 +70,14 @@ namespace i128 {
   static_assert(CastFrom(12) == 12, "");
   static_assert(CastFrom(12) == 12, "");
 
+  static_assert(CastFrom(AllOnes) == -1, "");
+  static_assert(CastFrom(AllOnes) == 0xFF, "");
+  static_assert(CastFrom(AllOnes) == -1, "");
+  static_assert(CastFrom(AllOnes) == 0x, "");
+  static_assert(CastFrom(AllOnes) == -1, "");
+  static_assert(CastFrom(AllOnes) == -1, "");
+  static_assert(CastFrom(AllOnes) == AllOnes, "");
+
   template 
   constexpr __int128 CastTo(T A) {
 int128_t B = (int128_t)A;

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][Interp] Fix value truncation when casting int128 to smaller size (PR #67961)

2023-10-02 Thread via cfe-commits
Timm =?utf-8?q?Bäder?= 
Message-ID:
In-Reply-To: 


llvmbot wrote:




@llvm/pr-subscribers-clang


Changes

Before this patch, we would run into an assertion in 
`APInt::get{S,Z}ExtValue()` because the `AllOnes` value had more than 64 active 
bits.

---
Full diff: https://github.com/llvm/llvm-project/pull/67961.diff


2 Files Affected:

- (modified) clang/lib/AST/Interp/IntegralAP.h (+13-9) 
- (modified) clang/test/AST/Interp/literals.cpp (+9) 


``diff
diff --git a/clang/lib/AST/Interp/IntegralAP.h 
b/clang/lib/AST/Interp/IntegralAP.h
index b2b367f30c238fe..f67b15dbc9b31ac 100644
--- a/clang/lib/AST/Interp/IntegralAP.h
+++ b/clang/lib/AST/Interp/IntegralAP.h
@@ -55,14 +55,14 @@ template  class IntegralAP final {
   bool operator<=(IntegralAP RHS) const { return V <= RHS.V; }
 
   explicit operator bool() const { return !V.isZero(); }
-  explicit operator int8_t() const { return V.getSExtValue(); }
-  explicit operator uint8_t() const { return V.getZExtValue(); }
-  explicit operator int16_t() const { return V.getSExtValue(); }
-  explicit operator uint16_t() const { return V.getZExtValue(); }
-  explicit operator int32_t() const { return V.getSExtValue(); }
-  explicit operator uint32_t() const { return V.getZExtValue(); }
-  explicit operator int64_t() const { return V.getSExtValue(); }
-  explicit operator uint64_t() const { return V.getZExtValue(); }
+  explicit operator int8_t() const { return truncateCast(V); }
+  explicit operator uint8_t() const { return truncateCast(V); }
+  explicit operator int16_t() const { return truncateCast(V); }
+  explicit operator uint16_t() const { return truncateCast(V); }
+  explicit operator int32_t() const { return truncateCast(V); }
+  explicit operator uint32_t() const { return truncateCast(V); }
+  explicit operator int64_t() const { return truncateCast(V); }
+  explicit operator uint64_t() const { return truncateCast(V); }
 
   template  static IntegralAP from(T Value, unsigned NumBits = 0) {
 assert(NumBits > 0);
@@ -210,7 +210,6 @@ template  class IntegralAP final {
   }
 
   static bool comp(IntegralAP A, IntegralAP *R) {
-assert(false);
 *R = IntegralAP(~A.V);
 return false;
   }
@@ -249,6 +248,11 @@ template  class IntegralAP final {
 R->V = A.V - B.V;
 return false; // Success!
   }
+
+  template  static T truncateCast(const APSInt ) {
+return std::is_signed_v ? V.trunc(sizeof(T) * 8).getSExtValue()
+   : V.trunc(sizeof(T) * 8).getZExtValue();
+  }
 };
 
 template 
diff --git a/clang/test/AST/Interp/literals.cpp 
b/clang/test/AST/Interp/literals.cpp
index eca0e4c2cbd26f1..65d211422ddac92 100644
--- a/clang/test/AST/Interp/literals.cpp
+++ b/clang/test/AST/Interp/literals.cpp
@@ -52,6 +52,9 @@ namespace i128 {
   constexpr int128_t Two = (int128_t)1 << 1ul;
   static_assert(Two == 2, "");
 
+  constexpr uint128_t AllOnes = ~static_cast(0);
+  static_assert(AllOnes == UINT128_MAX, "");
+
 #if __cplusplus >= 201402L
   template 
   constexpr T CastFrom(__int128_t A) {
@@ -67,6 +70,12 @@ namespace i128 {
   static_assert(CastFrom(12) == 12, "");
   static_assert(CastFrom(12) == 12, "");
 
+  static_assert(CastFrom(AllOnes) == -1, "");
+  static_assert(CastFrom(AllOnes) == 0xFF, "");
+  static_assert(CastFrom(AllOnes) == -1, "");
+  static_assert(CastFrom(AllOnes) == 0x, "");
+  static_assert(CastFrom(AllOnes) == -1, "");
+
   template 
   constexpr __int128 CastTo(T A) {
 int128_t B = (int128_t)A;

``




https://github.com/llvm/llvm-project/pull/67961
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][Interp] Fix value truncation when casting int128 to smaller size (PR #67961)

2023-10-02 Thread Timm Baeder via cfe-commits
Timm =?utf-8?q?Bäder?= 
Message-ID: 
In-Reply-To:


https://github.com/tbaederr created 
https://github.com/llvm/llvm-project/pull/67961

Before this patch, we would run into an assertion in 
`APInt::get{S,Z}ExtValue()` because the `AllOnes` value had more than 64 active 
bits.

>From 80bd890c332654458014c4acc20709b9cbb6eb90 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= 
Date: Sun, 1 Oct 2023 19:57:03 +0200
Subject: [PATCH 1/2] [clang][Interp] Implement IntegralAP::comp

---
 clang/lib/AST/Interp/IntegralAP.h  | 1 -
 clang/test/AST/Interp/literals.cpp | 3 +++
 2 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/clang/lib/AST/Interp/IntegralAP.h 
b/clang/lib/AST/Interp/IntegralAP.h
index b2b367f30c238fe..b29aac2a73e3243 100644
--- a/clang/lib/AST/Interp/IntegralAP.h
+++ b/clang/lib/AST/Interp/IntegralAP.h
@@ -210,7 +210,6 @@ template  class IntegralAP final {
   }
 
   static bool comp(IntegralAP A, IntegralAP *R) {
-assert(false);
 *R = IntegralAP(~A.V);
 return false;
   }
diff --git a/clang/test/AST/Interp/literals.cpp 
b/clang/test/AST/Interp/literals.cpp
index eca0e4c2cbd26f1..00182ba4ab1d918 100644
--- a/clang/test/AST/Interp/literals.cpp
+++ b/clang/test/AST/Interp/literals.cpp
@@ -52,6 +52,9 @@ namespace i128 {
   constexpr int128_t Two = (int128_t)1 << 1ul;
   static_assert(Two == 2, "");
 
+  constexpr uint128_t AllOnes = ~static_cast(0);
+  static_assert(AllOnes == static_cast(-1), "");
+
 #if __cplusplus >= 201402L
   template 
   constexpr T CastFrom(__int128_t A) {

>From 31ed85d44562ed1e5fe4714a5b659e5da8720f02 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= 
Date: Mon, 2 Oct 2023 10:46:22 +0200
Subject: [PATCH 2/2] [clang][Interp] Fix value truncation when casting int128
 to smaller size

---
 clang/lib/AST/Interp/IntegralAP.h  | 21 +
 clang/test/AST/Interp/literals.cpp |  8 +++-
 2 files changed, 20 insertions(+), 9 deletions(-)

diff --git a/clang/lib/AST/Interp/IntegralAP.h 
b/clang/lib/AST/Interp/IntegralAP.h
index b29aac2a73e3243..f67b15dbc9b31ac 100644
--- a/clang/lib/AST/Interp/IntegralAP.h
+++ b/clang/lib/AST/Interp/IntegralAP.h
@@ -55,14 +55,14 @@ template  class IntegralAP final {
   bool operator<=(IntegralAP RHS) const { return V <= RHS.V; }
 
   explicit operator bool() const { return !V.isZero(); }
-  explicit operator int8_t() const { return V.getSExtValue(); }
-  explicit operator uint8_t() const { return V.getZExtValue(); }
-  explicit operator int16_t() const { return V.getSExtValue(); }
-  explicit operator uint16_t() const { return V.getZExtValue(); }
-  explicit operator int32_t() const { return V.getSExtValue(); }
-  explicit operator uint32_t() const { return V.getZExtValue(); }
-  explicit operator int64_t() const { return V.getSExtValue(); }
-  explicit operator uint64_t() const { return V.getZExtValue(); }
+  explicit operator int8_t() const { return truncateCast(V); }
+  explicit operator uint8_t() const { return truncateCast(V); }
+  explicit operator int16_t() const { return truncateCast(V); }
+  explicit operator uint16_t() const { return truncateCast(V); }
+  explicit operator int32_t() const { return truncateCast(V); }
+  explicit operator uint32_t() const { return truncateCast(V); }
+  explicit operator int64_t() const { return truncateCast(V); }
+  explicit operator uint64_t() const { return truncateCast(V); }
 
   template  static IntegralAP from(T Value, unsigned NumBits = 0) {
 assert(NumBits > 0);
@@ -248,6 +248,11 @@ template  class IntegralAP final {
 R->V = A.V - B.V;
 return false; // Success!
   }
+
+  template  static T truncateCast(const APSInt ) {
+return std::is_signed_v ? V.trunc(sizeof(T) * 8).getSExtValue()
+   : V.trunc(sizeof(T) * 8).getZExtValue();
+  }
 };
 
 template 
diff --git a/clang/test/AST/Interp/literals.cpp 
b/clang/test/AST/Interp/literals.cpp
index 00182ba4ab1d918..65d211422ddac92 100644
--- a/clang/test/AST/Interp/literals.cpp
+++ b/clang/test/AST/Interp/literals.cpp
@@ -53,7 +53,7 @@ namespace i128 {
   static_assert(Two == 2, "");
 
   constexpr uint128_t AllOnes = ~static_cast(0);
-  static_assert(AllOnes == static_cast(-1), "");
+  static_assert(AllOnes == UINT128_MAX, "");
 
 #if __cplusplus >= 201402L
   template 
@@ -70,6 +70,12 @@ namespace i128 {
   static_assert(CastFrom(12) == 12, "");
   static_assert(CastFrom(12) == 12, "");
 
+  static_assert(CastFrom(AllOnes) == -1, "");
+  static_assert(CastFrom(AllOnes) == 0xFF, "");
+  static_assert(CastFrom(AllOnes) == -1, "");
+  static_assert(CastFrom(AllOnes) == 0x, "");
+  static_assert(CastFrom(AllOnes) == -1, "");
+
   template 
   constexpr __int128 CastTo(T A) {
 int128_t B = (int128_t)A;

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits