Skip to content

Commit 7d1ee63

Browse files
committed
[clangd] Fix a crash for accessing a null template decl returned by findExplicitReferences.
Summary: Fixes clangd/clangd#347. Reviewers: kadircet Subscribers: ilya-biryukov, MaskRay, jkorous, arphaman, usaxena95, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D78626
1 parent 264c07e commit 7d1ee63

File tree

2 files changed

+20
-4
lines changed

2 files changed

+20
-4
lines changed

clang-tools-extra/clangd/FindTarget.cpp

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -860,15 +860,17 @@ class ExplicitReferenceCollector
860860
// TemplateArgumentLoc is the only way to get locations for references to
861861
// template template parameters.
862862
bool TraverseTemplateArgumentLoc(TemplateArgumentLoc A) {
863+
llvm::SmallVector<const NamedDecl *, 1> Targets;
863864
switch (A.getArgument().getKind()) {
864865
case TemplateArgument::Template:
865866
case TemplateArgument::TemplateExpansion:
867+
if (const auto *D = A.getArgument()
868+
.getAsTemplateOrTemplatePattern()
869+
.getAsTemplateDecl())
870+
Targets.push_back(D);
866871
reportReference(ReferenceLoc{A.getTemplateQualifierLoc(),
867872
A.getTemplateNameLoc(),
868-
/*IsDecl=*/false,
869-
{A.getArgument()
870-
.getAsTemplateOrTemplatePattern()
871-
.getAsTemplateDecl()}},
873+
/*IsDecl=*/false, Targets},
872874
DynTypedNode::create(A.getArgument()));
873875
break;
874876
case TemplateArgument::Declaration:

clang-tools-extra/clangd/unittests/FindTargetTests.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1286,6 +1286,20 @@ TEST_F(FindExplicitReferencesTest, All) {
12861286
"1: targets = {}\n"
12871287
"2: targets = {T}\n"
12881288
},
1289+
// unknown template name should not crash.
1290+
{R"cpp(
1291+
template <template <typename> typename T>
1292+
struct Base {};
1293+
namespace foo {
1294+
template <typename $0^T>
1295+
struct $1^Derive : $2^Base<$3^T::template $4^Unknown> {};
1296+
}
1297+
)cpp",
1298+
"0: targets = {foo::Derive::T}, decl\n"
1299+
"1: targets = {foo::Derive}, decl\n"
1300+
"2: targets = {Base}\n"
1301+
"3: targets = {foo::Derive::T}\n"
1302+
"4: targets = {}, qualifier = 'T::'\n"},
12891303
};
12901304

12911305
for (const auto &C : Cases) {

0 commit comments

Comments
 (0)