Skip to content

Commit e23269b

Browse files
committed
[clangd] Fix crash on hover over large UL enums
1 parent 6b09f73 commit e23269b

File tree

2 files changed

+61
-2
lines changed

2 files changed

+61
-2
lines changed

clang-tools-extra/clangd/Hover.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -451,7 +451,7 @@ std::optional<std::string> printExprValue(const Expr *E,
451451

452452
// Show enums symbolically, not numerically like APValue::printPretty().
453453
if (T->isEnumeralType() && Constant.Val.isInt() &&
454-
Constant.Val.getInt().getSignificantBits() <= 64) {
454+
Constant.Val.getInt().isRepresentableByInt64()) {
455455
// Compare to int64_t to avoid bit-width match requirements.
456456
int64_t Val = Constant.Val.getInt().getExtValue();
457457
for (const EnumConstantDecl *ECD : T->castAsEnumDecl()->enumerators())
@@ -462,7 +462,7 @@ std::optional<std::string> printExprValue(const Expr *E,
462462
}
463463
// Show hex value of integers if they're at least 10 (or negative!)
464464
if (T->isIntegralOrEnumerationType() && Constant.Val.isInt() &&
465-
Constant.Val.getInt().getSignificantBits() <= 64 &&
465+
Constant.Val.getInt().isRepresentableByInt64() &&
466466
Constant.Val.getInt().uge(10))
467467
return llvm::formatv("{0} ({1})", Constant.Val.getAsString(Ctx, T),
468468
printHex(Constant.Val.getInt()))

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

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5015,6 +5015,65 @@ TEST(Hover, FunctionParameters) {
50155015
}
50165016
}
50175017

5018+
TEST(Hover, GH2381) {
5019+
Annotations Code(R"cpp(
5020+
struct Foo {
5021+
enum Bar {
5022+
A = -42UL,
5023+
B = ~0UL,
5024+
C = 0xFFFFFFFFFFFFFFFFUL,
5025+
};
5026+
};
5027+
constexpr auto va$a^ = Foo::A;
5028+
constexpr auto vb$b^ = Foo::B;
5029+
constexpr auto vc$c^ = Foo::C;
5030+
)cpp");
5031+
5032+
TestTU TU = TestTU::withCode(Code.code());
5033+
auto AST = TU.build();
5034+
5035+
{
5036+
auto H = getHover(AST, Code.point("a"), format::getLLVMStyle(), nullptr);
5037+
5038+
ASSERT_TRUE(H);
5039+
EXPECT_EQ(H->Name, "va");
5040+
EXPECT_EQ(H->Kind, index::SymbolKind::Variable);
5041+
EXPECT_EQ(H->NamespaceScope, "");
5042+
EXPECT_EQ(H->LocalScope, "");
5043+
EXPECT_EQ(H->Type, "const Foo::Bar");
5044+
EXPECT_EQ(H->Definition, "constexpr auto va = Foo::A");
5045+
// FIXME: Should be "A (FFFFFFFFFFFFFFD6)
5046+
EXPECT_EQ(H->Value, "18446744073709551574");
5047+
}
5048+
5049+
{
5050+
auto H = getHover(AST, Code.point("b"), format::getLLVMStyle(), nullptr);
5051+
5052+
ASSERT_TRUE(H);
5053+
EXPECT_EQ(H->Name, "vb");
5054+
EXPECT_EQ(H->Kind, index::SymbolKind::Variable);
5055+
EXPECT_EQ(H->NamespaceScope, "");
5056+
EXPECT_EQ(H->LocalScope, "");
5057+
EXPECT_EQ(H->Type, "const Foo::Bar");
5058+
EXPECT_EQ(H->Definition, "constexpr auto vb = Foo::B");
5059+
// FIXME: Should be "B (0xFFFFFFFFFFFFFFFF)");
5060+
EXPECT_EQ(H->Value, "18446744073709551615");
5061+
}
5062+
5063+
{
5064+
auto H = getHover(AST, Code.point("c"), format::getLLVMStyle(), nullptr);
5065+
5066+
ASSERT_TRUE(H);
5067+
EXPECT_EQ(H->Name, "vc");
5068+
EXPECT_EQ(H->Kind, index::SymbolKind::Variable);
5069+
EXPECT_EQ(H->NamespaceScope, "");
5070+
EXPECT_EQ(H->LocalScope, "");
5071+
EXPECT_EQ(H->Type, "const Foo::Bar");
5072+
EXPECT_EQ(H->Definition, "constexpr auto vc = Foo::C");
5073+
// FIXME: Should be "C (0xFFFFFFFFFFFFFFFF)");
5074+
EXPECT_EQ(H->Value, "18446744073709551615");
5075+
}
5076+
}
50185077
} // namespace
50195078
} // namespace clangd
50205079
} // namespace clang

0 commit comments

Comments
 (0)