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

Reply via email to