[clangd] Fix hover crashing on integral or enumeral casts

When pretty printing the value of an expression, we cannot infer from
the type of the expression the type of the constant that the expression
evaluates to, as the expression might contain a type cast.
This commit is contained in:
Georg Kotheimer 2022-05-31 21:57:51 +02:00 committed by Sam McCall
parent 8fb1bef60f
commit ce5ebf0b91
2 changed files with 30 additions and 2 deletions

View File

@ -429,7 +429,8 @@ llvm::Optional<std::string> printExprValue(const Expr *E,
return llvm::None;
// Show enums symbolically, not numerically like APValue::printPretty().
if (T->isEnumeralType() && Constant.Val.getInt().getMinSignedBits() <= 64) {
if (T->isEnumeralType() && Constant.Val.isInt() &&
Constant.Val.getInt().getMinSignedBits() <= 64) {
// Compare to int64_t to avoid bit-width match requirements.
int64_t Val = Constant.Val.getInt().getExtValue();
for (const EnumConstantDecl *ECD :
@ -440,7 +441,7 @@ llvm::Optional<std::string> printExprValue(const Expr *E,
.str();
}
// Show hex value of integers if they're at least 10 (or negative!)
if (T->isIntegralOrEnumerationType() &&
if (T->isIntegralOrEnumerationType() && Constant.Val.isInt() &&
Constant.Val.getInt().getMinSignedBits() <= 64 &&
Constant.Val.getInt().uge(10))
return llvm::formatv("{0} ({1})", Constant.Val.getAsString(Ctx, T),

View File

@ -3206,6 +3206,33 @@ TEST(Hover, HideBigInitializers) {
ASSERT_TRUE(H);
EXPECT_EQ(H->Definition, "int arr[]");
}
TEST(Hover, GlobalVarEnumeralCastNoCrash) {
Annotations T(R"cpp(
enum Test : unsigned long {};
unsigned global_var;
void foo() { Test v^al = (Test)(unsigned long)&global_var; }
)cpp");
TestTU TU = TestTU::withCode(T.code());
auto AST = TU.build();
auto HI = getHover(AST, T.point(), format::getLLVMStyle(), nullptr);
ASSERT_TRUE(HI);
EXPECT_EQ(*HI->Value, "&global_var");
}
TEST(Hover, GlobalVarIntCastNoCrash) {
Annotations T(R"cpp(
unsigned global_var;
int foo() { unsigned long a^ddress = (unsigned long)&global_var; }
)cpp");
TestTU TU = TestTU::withCode(T.code());
auto AST = TU.build();
auto HI = getHover(AST, T.point(), format::getLLVMStyle(), nullptr);
ASSERT_TRUE(HI);
EXPECT_EQ(*HI->Value, "&global_var");
}
} // namespace
} // namespace clangd
} // namespace clang