diff options
author | Haojian Wu <hokein.wu@gmail.com> | 2020-07-10 16:18:10 +0200 |
---|---|---|
committer | Haojian Wu <hokein.wu@gmail.com> | 2020-07-10 16:18:16 +0200 |
commit | 015a0faa5e9ef3095d521e1daf03fab9683ba028 (patch) | |
tree | 4f619ffad01de6d3bb2df28d4c237f39b5e90199 | |
parent | 22c8a08fd8a1487159564f74f24561964f6a6c97 (diff) | |
download | llvm-015a0faa5e9ef3095d521e1daf03fab9683ba028.tar.gz |
[clangd] Fix hover crash on InitListExpr.
Fixes https://github.com/clangd/clangd/issues/455
Differential Revision: https://reviews.llvm.org/D83546
-rw-r--r-- | clang-tools-extra/clangd/Hover.cpp | 12 | ||||
-rw-r--r-- | clang-tools-extra/clangd/unittests/HoverTests.cpp | 15 |
2 files changed, 26 insertions, 1 deletions
diff --git a/clang-tools-extra/clangd/Hover.cpp b/clang-tools-extra/clangd/Hover.cpp index cba933508fd5..8305a4724035 100644 --- a/clang-tools-extra/clangd/Hover.cpp +++ b/clang-tools-extra/clangd/Hover.cpp @@ -329,13 +329,23 @@ void fillFunctionTypeAndParams(HoverInfo &HI, const Decl *D, llvm::Optional<std::string> printExprValue(const Expr *E, const ASTContext &Ctx) { - Expr::EvalResult Constant; + // InitListExpr has two forms, syntactic and semantic. They are the same thing + // (refer to a same AST node) in most cases. + // When they are different, RAV returns the syntactic form, and we should feed + // the semantic form to EvaluateAsRValue. + if (const auto *ILE = llvm::dyn_cast<InitListExpr>(E)) { + if (!ILE->isSemanticForm()) + E = ILE->getSemanticForm(); + } + // Evaluating [[foo]]() as "&foo" isn't useful, and prevents us walking up // to the enclosing call. QualType T = E->getType(); if (T.isNull() || T->isFunctionType() || T->isFunctionPointerType() || T->isFunctionReferenceType()) return llvm::None; + + Expr::EvalResult Constant; // Attempt to evaluate. If expr is dependent, evaluation crashes! if (E->isValueDependent() || !E->EvaluateAsRValue(Constant, Ctx) || // Disable printing for record-types, as they are usually confusing and diff --git a/clang-tools-extra/clangd/unittests/HoverTests.cpp b/clang-tools-extra/clangd/unittests/HoverTests.cpp index 43f1e7142550..19ab6d63947b 100644 --- a/clang-tools-extra/clangd/unittests/HoverTests.cpp +++ b/clang-tools-extra/clangd/unittests/HoverTests.cpp @@ -801,6 +801,21 @@ class Foo {})cpp"; HI.LocalScope = "Foo::"; HI.Type = "int"; HI.AccessSpecifier = "public"; + }}, + {// No crash on InitListExpr. + R"cpp( + struct Foo { + int a[10]; + }; + constexpr Foo k2 = { + ^[[{]]1} // FIXME: why the hover range is 1 character? + }; + )cpp", + [](HoverInfo &HI) { + HI.Name = "expression"; + HI.Kind = index::SymbolKind::Unknown; + HI.Type = "int [10]"; + HI.Value = "{1}"; }}}; for (const auto &Case : Cases) { SCOPED_TRACE(Case.Code); |