diff --git a/clang-tools-extra/clangd/Compiler.cpp b/clang-tools-extra/clangd/Compiler.cpp --- a/clang-tools-extra/clangd/Compiler.cpp +++ b/clang-tools-extra/clangd/Compiler.cpp @@ -85,6 +85,11 @@ // Don't crash on `#pragma clang __debug parser_crash` CI->getPreprocessorOpts().DisablePragmaDebugCrash = true; + // Always default to raw container format as clangd doesn't registry any other + // and clang dies when faced with unknown formats. + CI->getHeaderSearchOpts().ModuleFormat = + PCHContainerOperations().getRawReader().getFormat().str(); + return CI; } diff --git a/clang-tools-extra/clangd/unittests/ModulesTests.cpp b/clang-tools-extra/clangd/unittests/ModulesTests.cpp --- a/clang-tools-extra/clangd/unittests/ModulesTests.cpp +++ b/clang-tools-extra/clangd/unittests/ModulesTests.cpp @@ -92,6 +92,24 @@ TU.build(); } +// Unknown module formats are a fatal failure for clang. Ensure we don't crash. +TEST(Modules, UnknownFormat) { + TestTU TU = TestTU::withCode(R"(#include "modular.h")"); + TU.OverlayRealFileSystemForModules = true; + TU.ExtraArgs.push_back("-Xclang"); + TU.ExtraArgs.push_back("-fmodule-format=obj"); + TU.ExtraArgs.push_back("-fmodule-map-file=" + testPath("m.modulemap")); + TU.ExtraArgs.push_back("-fmodules"); + TU.ExtraArgs.push_back("-fimplicit-modules"); + TU.AdditionalFiles["modular.h"] = ""; + TU.AdditionalFiles["m.modulemap"] = R"modulemap( + module M { + header "modular.h" + })modulemap"; + + // Test that we do not crash. + TU.build(); +} } // namespace } // namespace clangd } // namespace clang