Skip to content

Commit 35d867a

Browse files
committed
[clangd] Filter pch related flags coming from the user
Summary: PCH format is unstable, hence using a preamble built with a different version of clang (or even worse, a different compiler) might result in unexpected behaviour. PCH creation on the other hand is something clangd wouldn't want to perform, as it doesn't generate any output files. This patch makes sure clangd drops any PCH related compile commands after parsing the command line args. Fixes clangd/clangd#248 Reviewers: sammccall Subscribers: mgorny, ilya-biryukov, MaskRay, jkorous, arphaman, usaxena95, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D79669
1 parent 4f4d6c8 commit 35d867a

File tree

3 files changed

+66
-2
lines changed

3 files changed

+66
-2
lines changed

clang-tools-extra/clangd/Compiler.cpp

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,7 @@ void IgnoreDiagnostics::HandleDiagnostic(DiagnosticsEngine::Level DiagLevel,
4141
}
4242

4343
std::unique_ptr<CompilerInvocation>
44-
buildCompilerInvocation(const ParseInputs &Inputs,
45-
clang::DiagnosticConsumer &D,
44+
buildCompilerInvocation(const ParseInputs &Inputs, clang::DiagnosticConsumer &D,
4645
std::vector<std::string> *CC1Args) {
4746
std::vector<const char *> ArgStrs;
4847
for (const auto &S : Inputs.CompileCommand.CommandLine)
@@ -74,6 +73,15 @@ buildCompilerInvocation(const ParseInputs &Inputs,
7473
CI->getDependencyOutputOpts().HeaderIncludeOutputFile.clear();
7574
CI->getDependencyOutputOpts().DOTOutputFile.clear();
7675
CI->getDependencyOutputOpts().ModuleDependencyOutputDir.clear();
76+
77+
// Disable any pch generation/usage operations. Since serialized preamble
78+
// format is unstable, using an incompatible one might result in unexpected
79+
// behaviours, including crashes.
80+
CI->getPreprocessorOpts().ImplicitPCHInclude.clear();
81+
CI->getPreprocessorOpts().PrecompiledPreambleBytes = {0, false};
82+
CI->getPreprocessorOpts().PCHThroughHeader.clear();
83+
CI->getPreprocessorOpts().PCHWithHdrStop = false;
84+
CI->getPreprocessorOpts().PCHWithHdrStopCreate = false;
7785
return CI;
7886
}
7987

clang-tools-extra/clangd/unittests/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ add_unittest(ClangdUnitTests ClangdTests
3434
CodeCompletionStringsTests.cpp
3535
CollectMacrosTests.cpp
3636
CompileCommandsTests.cpp
37+
CompilerTests.cpp
3738
DexTests.cpp
3839
DiagnosticsTests.cpp
3940
DraftStoreTests.cpp
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
//===-- CompilerTests.cpp -------------------------------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#include "Compiler.h"
10+
#include "TestTU.h"
11+
#include "clang/Lex/PreprocessorOptions.h"
12+
#include "gmock/gmock.h"
13+
#include "gtest/gtest.h"
14+
15+
namespace clang {
16+
namespace clangd {
17+
namespace {
18+
19+
using testing::IsEmpty;
20+
21+
TEST(BuildCompilerInvocation, DropsPCH) {
22+
IgnoreDiagnostics Diags;
23+
TestTU TU;
24+
TU.AdditionalFiles["test.h.pch"] = "";
25+
26+
TU.ExtraArgs = {"-include-pch", "test.h.pch"};
27+
EXPECT_THAT(buildCompilerInvocation(TU.inputs(), Diags)
28+
->getPreprocessorOpts()
29+
.ImplicitPCHInclude,
30+
IsEmpty());
31+
32+
// Transparent include translation
33+
TU.ExtraArgs = {"-include", "test.h"};
34+
EXPECT_THAT(buildCompilerInvocation(TU.inputs(), Diags)
35+
->getPreprocessorOpts()
36+
.ImplicitPCHInclude,
37+
IsEmpty());
38+
39+
// CL mode parsing.
40+
TU.AdditionalFiles["test.pch"] = "";
41+
TU.ExtraArgs = {"--driver-mode=cl"};
42+
TU.ExtraArgs.push_back("/Yutest.h");
43+
EXPECT_THAT(buildCompilerInvocation(TU.inputs(), Diags)
44+
->getPreprocessorOpts()
45+
.ImplicitPCHInclude,
46+
IsEmpty());
47+
EXPECT_THAT(buildCompilerInvocation(TU.inputs(), Diags)
48+
->getPreprocessorOpts()
49+
.PCHThroughHeader,
50+
IsEmpty());
51+
}
52+
53+
} // namespace
54+
} // namespace clangd
55+
} // namespace clang

0 commit comments

Comments
 (0)