diff --git a/clang-tools-extra/clangd/Hover.cpp b/clang-tools-extra/clangd/Hover.cpp --- a/clang-tools-extra/clangd/Hover.cpp +++ b/clang-tools-extra/clangd/Hover.cpp @@ -242,12 +242,13 @@ // FIXME: handle variadics. } -llvm::Optional printExprValue(const Expr *E, const ASTContext &Ctx) { +llvm::Optional printExprValue(const Expr *E, + const ASTContext &Ctx) { Expr::EvalResult Constant; // Evaluating [[foo]]() as "&foo" isn't useful, and prevents us walking up // to the enclosing call. QualType T = E->getType(); - if (T->isFunctionType() || T->isFunctionPointerType() || + if (T.isNull() || T->isFunctionType() || T->isFunctionPointerType() || T->isFunctionReferenceType()) return llvm::None; // Attempt to evaluate. If expr is dependent, evaluation crashes! diff --git a/clang-tools-extra/clangd/unittests/HoverTests.cpp b/clang-tools-extra/clangd/unittests/HoverTests.cpp --- a/clang-tools-extra/clangd/unittests/HoverTests.cpp +++ b/clang-tools-extra/clangd/unittests/HoverTests.cpp @@ -506,6 +506,24 @@ HI.NamespaceScope = ""; HI.Value = "&\"1234\"[0]"; }}, + {R"cpp(// Should not crash + template + struct Tmpl { + Tmpl(int name); + }; + + template + void boom(int name) { + new Tmpl([[na^me]]); + })cpp", + [](HoverInfo &HI) { + HI.Name = "name"; + HI.Definition = "int name"; + HI.Kind = index::SymbolKind::Parameter; + HI.Type = "int"; + HI.NamespaceScope = ""; + HI.LocalScope = "boom::"; + }}, }; for (const auto &Case : Cases) { SCOPED_TRACE(Case.Code);