diff --git a/clang-tools-extra/clangd/unittests/SymbolCollectorTests.cpp b/clang-tools-extra/clangd/unittests/SymbolCollectorTests.cpp --- a/clang-tools-extra/clangd/unittests/SymbolCollectorTests.cpp +++ b/clang-tools-extra/clangd/unittests/SymbolCollectorTests.cpp @@ -1801,6 +1801,23 @@ EXPECT_THAT(TU.headerSymbols(), Not(Contains(QName("X")))); } +TEST_F(SymbolCollectorTest, NoCrashOnObjCMethodCStyleParam) { + auto TU = TestTU::withCode(R"objc( + /*error-ok*/ + @interface Foo + - (void)fun:(bool)foo + bar:(bool)bar, + baz:(bool)baz; + @end + )objc"); + TU.ExtraArgs.push_back("-xobjective-c++"); + + TU.build(); + // We mostly care about not crashing, but verify that we didn't insert garbage + // about X too. + EXPECT_THAT(TU.headerSymbols(), Not(Contains(QName("X")))); +} + } // namespace } // namespace clangd } // namespace clang diff --git a/clang/lib/Sema/SemaCodeComplete.cpp b/clang/lib/Sema/SemaCodeComplete.cpp --- a/clang/lib/Sema/SemaCodeComplete.cpp +++ b/clang/lib/Sema/SemaCodeComplete.cpp @@ -3493,6 +3493,14 @@ return Result.TakeString(); } + if (Method->param_size() > Sel.getNumArgs()) { + // FIXME: We could be smarter about this, but for now just avoid a crash + // below by returning early. + Result.AddTypedTextChunk( + Result.getAllocator().CopyString(ND->getNameAsString())); + return Result.TakeString(); + } + std::string SelName = Sel.getNameForSlot(0).str(); SelName += ':'; if (StartParameter == 0)