[clang-tools-extra] d5cfdca - [clangd] Allow hover over 128-bit variable without crashing (#71415)

Bjorn Pettersson via cfe-commits cfe-commits at lists.llvm.org
Wed Nov 8 05:13:43 PST 2023


Author: Björn Pettersson
Date: 2023-11-08T14:13:11+01:00
New Revision: d5cfdcaacbd36d6c25011f03a4eb51137f7a804a

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

LOG: [clangd] Allow hover over 128-bit variable without crashing (#71415)

When hovering over variables larger than 64 bits, with more than 64
active bits, there were assertion failures since Hover is trying to
print the value as a 64-bit hex value.

There is already protection avoiding to call printHex if there is more
than 64 significant bits. And we already truncate and print negative
values using only 32 bits, when possible. So we can simply truncate
values with more than 64 bits to avoid the assert when using
getZExtValue. The result will be that for example a negative 128 bit
variable is printed using 64 bits, when possible.

There is still no support for printing more than 64 bits. That would
involve more changes since for example llvm::FormatterNumber is limited
to 64 bits.

This is a second attempt at landing this patch. Now with protection
to ensure we use a triple that supports __int128_t.

Added: 
    

Modified: 
    clang-tools-extra/clangd/Hover.cpp
    clang-tools-extra/clangd/unittests/HoverTests.cpp

Removed: 
    


################################################################################
diff  --git a/clang-tools-extra/clangd/Hover.cpp b/clang-tools-extra/clangd/Hover.cpp
index 7f7b5513dff6fee..a868d3bb4e3fa1d 100644
--- a/clang-tools-extra/clangd/Hover.cpp
+++ b/clang-tools-extra/clangd/Hover.cpp
@@ -408,7 +408,9 @@ void fillFunctionTypeAndParams(HoverInfo &HI, const Decl *D,
 // -2    => 0xfffffffe
 // -2^32 => 0xffffffff00000000
 static llvm::FormattedNumber printHex(const llvm::APSInt &V) {
-  uint64_t Bits = V.getZExtValue();
+  assert(V.getSignificantBits() <= 64 && "Can't print more than 64 bits.");
+  uint64_t Bits =
+      V.getBitWidth() > 64 ? V.trunc(64).getZExtValue() : V.getZExtValue();
   if (V.isNegative() && V.getSignificantBits() <= 32)
     return llvm::format_hex(uint32_t(Bits), 0);
   return llvm::format_hex(Bits, 0);

diff  --git a/clang-tools-extra/clangd/unittests/HoverTests.cpp b/clang-tools-extra/clangd/unittests/HoverTests.cpp
index 063a60db044060e..35db757b9c15b5d 100644
--- a/clang-tools-extra/clangd/unittests/HoverTests.cpp
+++ b/clang-tools-extra/clangd/unittests/HoverTests.cpp
@@ -3349,6 +3349,20 @@ TEST(Hover, NoCrashAPInt64) {
   getHover(AST, T.point(), format::getLLVMStyle(), nullptr);
 }
 
+TEST(Hover, NoCrashInt128) {
+  Annotations T(R"cpp(
+    constexpr __int128_t value = -4;
+    void foo() { va^lue; }
+  )cpp");
+  auto TU = TestTU::withCode(T.code());
+  // Need a triple that support __int128_t.
+  TU.ExtraArgs.push_back("--target=x86_64-pc-linux-gnu");
+  auto AST = TU.build();
+  auto H = getHover(AST, T.point(), format::getLLVMStyle(), nullptr);
+  ASSERT_TRUE(H);
+  EXPECT_EQ(H->Value, "-4 (0xfffffffc)");
+}
+
 TEST(Hover, DocsFromMostSpecial) {
   Annotations T(R"cpp(
   // doc1


        


More information about the cfe-commits mailing list