[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 <emilydror01@gmail.com>
This commit is contained in:
parent
f5f8435605
commit
192883904a
2 changed files with 31 additions and 2 deletions
|
|
@ -347,8 +347,8 @@ public:
|
|||
});
|
||||
}
|
||||
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,
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in a new issue