Author: Emily Dror Date: 2026-02-20T01:55:09+03:00 New Revision: 192883904a90945efecdbbb3530e9507e45e8378
URL: https://github.com/llvm/llvm-project/commit/192883904a90945efecdbbb3530e9507e45e8378 DIFF: https://github.com/llvm/llvm-project/commit/192883904a90945efecdbbb3530e9507e45e8378.diff LOG: [clangd] Guard against null TemplateName in DumpVisitor (#181554) Add a guard against null values for TemplateName in DumpVisitor::TraverseTemplateName. clangd’s DumpVisitor may attempt to traverse a null TemplateName when handling dependent nested template names. On LLVM main this can lead to a crash in TemplateName::getKind(). Add a defensive check in DumpVisitor::TraverseTemplateName() to skip null TemplateName instances before invoking traverseNode(). Following the same design as other functions in the class. No functional change is intended beyond preventing the crash. Fixes: #180902 --------- Signed-off-by: Emily Dror <[email protected]> Added: Modified: clang-tools-extra/clangd/DumpAST.cpp clang-tools-extra/clangd/unittests/DumpASTTests.cpp Removed: ################################################################################ diff --git a/clang-tools-extra/clangd/DumpAST.cpp b/clang-tools-extra/clangd/DumpAST.cpp index cd409a2b930ef..2b673128493b3 100644 --- a/clang-tools-extra/clangd/DumpAST.cpp +++ b/clang-tools-extra/clangd/DumpAST.cpp @@ -347,8 +347,8 @@ class DumpVisitor : public RecursiveASTVisitor<DumpVisitor> { }); } bool TraverseTemplateName(const TemplateName &TN) { - return traverseNode("template name", TN, - [&] { Base::TraverseTemplateName(TN); }); + return TN.isNull() || traverseNode("template name", TN, + [&] { Base::TraverseTemplateName(TN); }); } bool TraverseTemplateArgumentLoc(const TemplateArgumentLoc &TAL) { return traverseNode("template argument", TAL, diff --git a/clang-tools-extra/clangd/unittests/DumpASTTests.cpp b/clang-tools-extra/clangd/unittests/DumpASTTests.cpp index 5c857d0b8ae3e..7b7e8ae000bf0 100644 --- a/clang-tools-extra/clangd/unittests/DumpASTTests.cpp +++ b/clang-tools-extra/clangd/unittests/DumpASTTests.cpp @@ -227,6 +227,35 @@ TEST(DumpASTTests, UnbalancedBraces) { ASSERT_EQ(Node.range, Case.range("func")); } +TEST(DumpASTTests, NestedTemplates) { + // Test that we don't crash while trying to dump AST of a template function + // with nested template names such as Foo<V>::template Bar<W>::Value. + const char *Code = R"cpp( +template <typename T> +struct TypeA { + template <typename U> + struct TypeB { + static U Value; + }; +}; + +template <typename V, typename W> +auto func() { + return TypeA<V>::template TypeB<W>::Value; +} + )cpp"; + + ParsedAST AST = TestTU::withCode(Code).build(); + const NamedDecl &Func = findDecl(AST, [](const NamedDecl &D) { + return isa<FunctionDecl>(D) && D.getNameAsString() == "func"; + }); + + const ASTNode Node = + dumpAST(DynTypedNode::create(Func), AST.getTokens(), AST.getASTContext()); + + EXPECT_EQ(Node.kind, "Function"); +} + } // namespace } // namespace clangd } // namespace clang _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
