This revision was automatically updated to reflect the committed changes. Closed by commit rG7d1ee639cb9e: [clangd] Fix a crash for accessing a null template decl returned by… (authored by hokein).
Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D78626/new/ https://reviews.llvm.org/D78626 Files: clang-tools-extra/clangd/FindTarget.cpp clang-tools-extra/clangd/unittests/FindTargetTests.cpp Index: clang-tools-extra/clangd/unittests/FindTargetTests.cpp =================================================================== --- clang-tools-extra/clangd/unittests/FindTargetTests.cpp +++ clang-tools-extra/clangd/unittests/FindTargetTests.cpp @@ -1286,6 +1286,20 @@ "1: targets = {}\n" "2: targets = {T}\n" }, + // unknown template name should not crash. + {R"cpp( + template <template <typename> typename T> + struct Base {}; + namespace foo { + template <typename $0^T> + struct $1^Derive : $2^Base<$3^T::template $4^Unknown> {}; + } + )cpp", + "0: targets = {foo::Derive::T}, decl\n" + "1: targets = {foo::Derive}, decl\n" + "2: targets = {Base}\n" + "3: targets = {foo::Derive::T}\n" + "4: targets = {}, qualifier = 'T::'\n"}, }; for (const auto &C : Cases) { Index: clang-tools-extra/clangd/FindTarget.cpp =================================================================== --- clang-tools-extra/clangd/FindTarget.cpp +++ clang-tools-extra/clangd/FindTarget.cpp @@ -860,15 +860,17 @@ // TemplateArgumentLoc is the only way to get locations for references to // template template parameters. bool TraverseTemplateArgumentLoc(TemplateArgumentLoc A) { + llvm::SmallVector<const NamedDecl *, 1> Targets; switch (A.getArgument().getKind()) { case TemplateArgument::Template: case TemplateArgument::TemplateExpansion: + if (const auto *D = A.getArgument() + .getAsTemplateOrTemplatePattern() + .getAsTemplateDecl()) + Targets.push_back(D); reportReference(ReferenceLoc{A.getTemplateQualifierLoc(), A.getTemplateNameLoc(), - /*IsDecl=*/false, - {A.getArgument() - .getAsTemplateOrTemplatePattern() - .getAsTemplateDecl()}}, + /*IsDecl=*/false, Targets}, DynTypedNode::create(A.getArgument())); break; case TemplateArgument::Declaration:
Index: clang-tools-extra/clangd/unittests/FindTargetTests.cpp =================================================================== --- clang-tools-extra/clangd/unittests/FindTargetTests.cpp +++ clang-tools-extra/clangd/unittests/FindTargetTests.cpp @@ -1286,6 +1286,20 @@ "1: targets = {}\n" "2: targets = {T}\n" }, + // unknown template name should not crash. + {R"cpp( + template <template <typename> typename T> + struct Base {}; + namespace foo { + template <typename $0^T> + struct $1^Derive : $2^Base<$3^T::template $4^Unknown> {}; + } + )cpp", + "0: targets = {foo::Derive::T}, decl\n" + "1: targets = {foo::Derive}, decl\n" + "2: targets = {Base}\n" + "3: targets = {foo::Derive::T}\n" + "4: targets = {}, qualifier = 'T::'\n"}, }; for (const auto &C : Cases) { Index: clang-tools-extra/clangd/FindTarget.cpp =================================================================== --- clang-tools-extra/clangd/FindTarget.cpp +++ clang-tools-extra/clangd/FindTarget.cpp @@ -860,15 +860,17 @@ // TemplateArgumentLoc is the only way to get locations for references to // template template parameters. bool TraverseTemplateArgumentLoc(TemplateArgumentLoc A) { + llvm::SmallVector<const NamedDecl *, 1> Targets; switch (A.getArgument().getKind()) { case TemplateArgument::Template: case TemplateArgument::TemplateExpansion: + if (const auto *D = A.getArgument() + .getAsTemplateOrTemplatePattern() + .getAsTemplateDecl()) + Targets.push_back(D); reportReference(ReferenceLoc{A.getTemplateQualifierLoc(), A.getTemplateNameLoc(), - /*IsDecl=*/false, - {A.getArgument() - .getAsTemplateOrTemplatePattern() - .getAsTemplateDecl()}}, + /*IsDecl=*/false, Targets}, DynTypedNode::create(A.getArgument())); break; case TemplateArgument::Declaration:
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits