Skip to content

Conversation

tbaederr
Copy link
Contributor

@tbaederr tbaederr commented Nov 8, 2023

In Interp.h, when a add/sub/mul fails, we call this code and expect to get an APSInt back that can handle more than the current bitwidth of the type.

@llvmbot llvmbot added clang Clang issues not falling into any other category clang:frontend Language frontend issues, e.g. anything involving "Sema" labels Nov 8, 2023
@llvmbot
Copy link
Member

llvmbot commented Nov 8, 2023

@llvm/pr-subscribers-clang

Author: Timm Baeder (tbaederr)

Changes

In Interp.h, when a add/sub/mul fails, we call this code and expect to get an APSInt back that can handle more than the current bitwidth of the type.


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

2 Files Affected:

  • (modified) clang/lib/AST/Interp/IntegralAP.h (+9-1)
  • (modified) clang/test/AST/Interp/intap.cpp (+7-2)
diff --git a/clang/lib/AST/Interp/IntegralAP.h b/clang/lib/AST/Interp/IntegralAP.h
index 6d301bad784af47..a24e283cb2e7cda 100644
--- a/clang/lib/AST/Interp/IntegralAP.h
+++ b/clang/lib/AST/Interp/IntegralAP.h
@@ -119,7 +119,15 @@ template <bool Signed> class IntegralAP final {
 
   constexpr unsigned bitWidth() const { return V.getBitWidth(); }
 
-  APSInt toAPSInt(unsigned Bits = 0) const { return APSInt(V, Signed); }
+  APSInt toAPSInt(unsigned Bits = 0) const {
+    if (Bits == 0)
+      Bits = bitWidth();
+
+    if constexpr (Signed)
+      return APSInt(V.sext(Bits), !Signed);
+    else
+      return APSInt(V.zext(Bits), !Signed);
+  }
   APValue toAPValue() const { return APValue(APSInt(V, Signed)); }
 
   bool isZero() const { return V.isZero(); }
diff --git a/clang/test/AST/Interp/intap.cpp b/clang/test/AST/Interp/intap.cpp
index 45961e6fc74b7a7..898d5795e1ffd5a 100644
--- a/clang/test/AST/Interp/intap.cpp
+++ b/clang/test/AST/Interp/intap.cpp
@@ -59,11 +59,16 @@ namespace i128 {
 
   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 {{outside the range}} \
+                                         // expected-note {{value 170141183460469231731687303715884105728 is outside the range}} \
                                          // ref-error {{must be initialized by a constant expression}} \
-                                         // ref-note {{outside the range}}
+                                         // ref-note {{value 170141183460469231731687303715884105728 is outside the range}}
   constexpr int128_t Two = (int128_t)1 << 1ul;
   static_assert(Two == 2, "");
   static_assert(Two, "");

@tbaederr tbaederr changed the title [clang][Interp] Consider bit width in toAPSInt() [clang][Interp] Consider bit width in IntegralAP::toAPSInt() Nov 8, 2023
Copy link
Collaborator

@AaronBallman AaronBallman left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@tbaederr tbaederr merged commit 8feb083 into llvm:main Nov 9, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
clang:frontend Language frontend issues, e.g. anything involving "Sema" clang Clang issues not falling into any other category
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants