gkll updated this revision to Diff 433211.
gkll added a comment.
Use `uintptr_t` instead of `unsigned long` for the casts, to ensure the pointer
always fits into the integer type.
For example on Windows x64 that was previously not the case, because there
`unsigned long` is only 32-bits wide.
Thus the pointer got truncated during the cast, which resulted in `getHover()`
returning `None` instead of `&global_var`.
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D126498/new/
https://reviews.llvm.org/D126498
Files:
clang-tools-extra/clangd/Hover.cpp
clang-tools-extra/clangd/unittests/HoverTests.cpp
clang-tools-extra/clangd/unittests/TestTU.cpp
clang-tools-extra/clangd/unittests/TestTU.h
Index: clang-tools-extra/clangd/unittests/TestTU.h
===================================================================
--- clang-tools-extra/clangd/unittests/TestTU.h
+++ clang-tools-extra/clangd/unittests/TestTU.h
@@ -59,6 +59,9 @@
// Extra arguments for the compiler invocation.
std::vector<std::string> ExtraArgs;
+ // Omit predefined macros.
+ bool OmitPredefinedMacros = true;
+
TidyProvider ClangTidyProvider = {};
// Index to use when building AST.
const SymbolIndex *ExternalIndex = nullptr;
Index: clang-tools-extra/clangd/unittests/TestTU.cpp
===================================================================
--- clang-tools-extra/clangd/unittests/TestTU.cpp
+++ clang-tools-extra/clangd/unittests/TestTU.cpp
@@ -40,9 +40,12 @@
ParseInputs Inputs;
Inputs.FeatureModules = FeatureModules;
auto &Argv = Inputs.CompileCommand.CommandLine;
- // In tests, omit predefined macros (__GNUC__ etc) for a 25% speedup.
- // There are hundreds, and we'd generate, parse, serialize, and re-parse them!
- Argv = {"clang", "-Xclang", "-undef"};
+ Argv = {"clang", "-Xclang", };
+ // In tests, unless explicitly specified otherwise, omit predefined macros
+ // (__GNUC__ etc) for a 25% speedup. There are hundreds, and we'd generate,
+ // parse, serialize, and re-parse them!
+ if (OmitPredefinedMacros)
+ Argv.push_back("-undef");
// FIXME: this shouldn't need to be conditional, but it breaks a
// GoToDefinition test for some reason (getMacroArgExpandedLocation fails).
if (!HeaderCode.empty()) {
Index: clang-tools-extra/clangd/unittests/HoverTests.cpp
===================================================================
--- clang-tools-extra/clangd/unittests/HoverTests.cpp
+++ clang-tools-extra/clangd/unittests/HoverTests.cpp
@@ -3206,6 +3206,41 @@
ASSERT_TRUE(H);
EXPECT_EQ(H->Definition, "int arr[]");
}
+
+TEST(Hover, GlobalVarEnumeralCastNoCrash) {
+ Annotations T(R"cpp(
+ using uintptr_t = __UINTPTR_TYPE__;
+ enum Test : uintptr_t {};
+ unsigned global_var;
+ void foo() {
+ Test v^al = static_cast<Test>(reinterpret_cast<uintptr_t>(&global_var));
+ }
+ )cpp");
+
+ TestTU TU = TestTU::withCode(T.code());
+ TU.OmitPredefinedMacros = false;
+ 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(
+ using uintptr_t = __UINTPTR_TYPE__;
+ unsigned global_var;
+ void foo() {
+ uintptr_t a^ddress = reinterpret_cast<uintptr_t>(&global_var);
+ }
+ )cpp");
+
+ TestTU TU = TestTU::withCode(T.code());
+ TU.OmitPredefinedMacros = false;
+ 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
Index: clang-tools-extra/clangd/Hover.cpp
===================================================================
--- clang-tools-extra/clangd/Hover.cpp
+++ clang-tools-extra/clangd/Hover.cpp
@@ -429,7 +429,8 @@
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 @@
.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),
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits