diff --git a/clang/lib/Index/IndexTypeSourceInfo.cpp b/clang/lib/Index/IndexTypeSourceInfo.cpp index b986ccde574525..58ad0799062ca3 100644 --- a/clang/lib/Index/IndexTypeSourceInfo.cpp +++ b/clang/lib/Index/IndexTypeSourceInfo.cpp @@ -52,6 +52,9 @@ class TypeIndexer : public RecursiveASTVisitor { bool VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TTPL) { SourceLocation Loc = TTPL.getNameLoc(); TemplateTypeParmDecl *TTPD = TTPL.getDecl(); + if (!TTPD) + return false; + return IndexCtx.handleReference(TTPD, Loc, Parent, ParentDC, SymbolRoleSet()); } diff --git a/clang/test/Index/gh89389.cpp b/clang/test/Index/gh89389.cpp new file mode 100644 index 00000000000000..0458d0a64083d8 --- /dev/null +++ b/clang/test/Index/gh89389.cpp @@ -0,0 +1,16 @@ +// RUN: c-index-test -test-load-source all %s -std=gnu++20 -fno-delayed-template-parsing + +namespace test18 { +template +concept False = false; + +template struct Foo { T t; }; + +template requires False +Foo(T) -> Foo; + +template +using Bar = Foo; + +Bar s = {1}; +} // namespace test18 diff --git a/clang/tools/libclang/CIndex.cpp b/clang/tools/libclang/CIndex.cpp index cbc1d85bb33dfc..8fd723a90e5565 100644 --- a/clang/tools/libclang/CIndex.cpp +++ b/clang/tools/libclang/CIndex.cpp @@ -1693,12 +1693,16 @@ bool CursorVisitor::VisitTagTypeLoc(TagTypeLoc TL) { } bool CursorVisitor::VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) { - if (const auto *TC = TL.getDecl()->getTypeConstraint()) { + TemplateTypeParmDecl *D = TL.getDecl(); + if (!D) + return true; + + if (const auto *TC = D->getTypeConstraint()) { if (VisitTypeConstraint(*TC)) return true; } - return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU)); + return Visit(MakeCursorTypeRef(D, TL.getNameLoc(), TU)); } bool CursorVisitor::VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) { diff --git a/clang/unittests/Index/IndexTests.cpp b/clang/unittests/Index/IndexTests.cpp index 8e9a1c6bf88245..0db8a4b98c2025 100644 --- a/clang/unittests/Index/IndexTests.cpp +++ b/clang/unittests/Index/IndexTests.cpp @@ -453,6 +453,33 @@ TEST(IndexTest, ReadWriteRoles) { WrittenAt(Position(6, 17)))))); } +TEST(IndexTest, gh89389) { + std::string Code = R"cpp( + namespace test18 { + template + concept False = false; + + template struct Foo { T t; }; + + template requires False + Foo(T) -> Foo; + + template + using Bar = Foo; + + Bar s = {1}; + } // namespace test18 + )cpp"; + auto Index = std::make_shared(); + IndexingOptions Opts; + Opts.IndexTemplateParameters = true; + + // This test case is invalid code, so the expected return value is `false`. + // What is being tested is that there is no crash. + EXPECT_FALSE(tooling::runToolOnCodeWithArgs( + std::make_unique(Index, Opts), Code, {"-std=c++20"})); +} + } // namespace } // namespace index } // namespace clang