Skip to content

Commit d5cfdca

Browse files
committed
[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.
1 parent fdf99b2 commit d5cfdca

File tree

2 files changed

+17
-1
lines changed

2 files changed

+17
-1
lines changed

clang-tools-extra/clangd/Hover.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -408,7 +408,9 @@ void fillFunctionTypeAndParams(HoverInfo &HI, const Decl *D,
408408
// -2 => 0xfffffffe
409409
// -2^32 => 0xffffffff00000000
410410
static llvm::FormattedNumber printHex(const llvm::APSInt &V) {
411-
uint64_t Bits = V.getZExtValue();
411+
assert(V.getSignificantBits() <= 64 && "Can't print more than 64 bits.");
412+
uint64_t Bits =
413+
V.getBitWidth() > 64 ? V.trunc(64).getZExtValue() : V.getZExtValue();
412414
if (V.isNegative() && V.getSignificantBits() <= 32)
413415
return llvm::format_hex(uint32_t(Bits), 0);
414416
return llvm::format_hex(Bits, 0);

clang-tools-extra/clangd/unittests/HoverTests.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3349,6 +3349,20 @@ TEST(Hover, NoCrashAPInt64) {
33493349
getHover(AST, T.point(), format::getLLVMStyle(), nullptr);
33503350
}
33513351

3352+
TEST(Hover, NoCrashInt128) {
3353+
Annotations T(R"cpp(
3354+
constexpr __int128_t value = -4;
3355+
void foo() { va^lue; }
3356+
)cpp");
3357+
auto TU = TestTU::withCode(T.code());
3358+
// Need a triple that support __int128_t.
3359+
TU.ExtraArgs.push_back("--target=x86_64-pc-linux-gnu");
3360+
auto AST = TU.build();
3361+
auto H = getHover(AST, T.point(), format::getLLVMStyle(), nullptr);
3362+
ASSERT_TRUE(H);
3363+
EXPECT_EQ(H->Value, "-4 (0xfffffffc)");
3364+
}
3365+
33523366
TEST(Hover, DocsFromMostSpecial) {
33533367
Annotations T(R"cpp(
33543368
// doc1

0 commit comments

Comments
 (0)