Skip to content

Commit 77f8041

Browse files
committed
[clang][cas] Fix cache poison error with diagnostic options
Avoid emitting DIAGNOSTIC_OPTIONS block when caching. In cached builds, there is no benefit to emitting diagnostic options into the PCM/PCH, since we know it can never mismatch. Remove this block, because it can contain volatile options such as fmessage-length that should not have any impact on the output when using cached diagnostics. Also add a test for -ferror-limit: while it is okay to clear this option it's important to test it since it relies on the fact we are not caching compilation failures. Unlike the other "formatting" options, this affects the set of diagnostics passed to the diagnostic consumer. rdar://109285136 (cherry picked from commit e939ada)
1 parent 692d150 commit 77f8041

File tree

7 files changed

+73
-2
lines changed

7 files changed

+73
-2
lines changed

clang/include/clang/Driver/Options.td

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6650,6 +6650,11 @@ defm cache_disable_replay : BoolFOption<"cache-disable-replay",
66506650
PosFlag<SetTrue, [], "Disable replaying a cached compile job">,
66516651
NegFlag<SetFalse>>;
66526652

6653+
defm modules_skip_diagnostic_options : BoolFOption<"modules-skip-diagnostic-options",
6654+
HeaderSearchOpts<"ModulesSkipDiagnosticOptions">, DefaultFalse,
6655+
PosFlag<SetTrue, [], "Disable writing diagnostic options">,
6656+
NegFlag<SetFalse>>;
6657+
66536658
def fcompilation_caching_service_path : Separate<["-"], "fcompilation-caching-service-path">,
66546659
Group<f_Group>, MetaVarName<"<pathname>">,
66556660
HelpText<"Specify the socket path for connecting to a remote caching service">,

clang/include/clang/Lex/HeaderSearchOptions.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,9 @@ class HeaderSearchOptions {
216216

217217
unsigned ModulesValidateDiagnosticOptions : 1;
218218

219+
/// Whether to entirely skip writing diagnostic options.
220+
unsigned ModulesSkipDiagnosticOptions : 1;
221+
219222
unsigned ModulesHashContent : 1;
220223

221224
/// Whether we should include all things that could impact the module in the
@@ -234,7 +237,8 @@ class HeaderSearchOptions {
234237
ModulesValidateOncePerBuildSession(false),
235238
ModulesValidateSystemHeaders(false),
236239
ValidateASTInputFilesContent(false), UseDebugInfo(false),
237-
ModulesValidateDiagnosticOptions(true), ModulesHashContent(false),
240+
ModulesValidateDiagnosticOptions(true),
241+
ModulesSkipDiagnosticOptions(false), ModulesHashContent(false),
238242
ModulesStrictContextHash(false) {}
239243

240244
/// AddPath - Add the \p Path path to the specified \p Group list.

clang/lib/Frontend/CompileJobCacheKey.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,8 @@ createCompileJobCacheKeyImpl(ObjectStore &CAS, DiagnosticsEngine &Diags,
9494
DiagOpts.UseANSIEscapeCodes = false;
9595
DiagOpts.VerifyDiagnostics = false;
9696
DiagOpts.setVerifyIgnoreUnexpected(DiagnosticLevelMask::None);
97+
// Note: ErrorLimit affects the set of diagnostics emitted, but since we do
98+
// not cache compilation failures, it's safe to clear here.
9799
DiagOpts.ErrorLimit = 0;
98100
DiagOpts.MacroBacktraceLimit = 0;
99101
DiagOpts.SnippetLineLimit = 0;

clang/lib/Serialization/ASTWriter.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1161,6 +1161,9 @@ ASTFileSignature ASTWriter::writeUnhashedControlBlock(Preprocessor &PP,
11611161
// Diagnostic options.
11621162
const auto &Diags = Context.getDiagnostics();
11631163
const DiagnosticOptions &DiagOpts = Diags.getDiagnosticOptions();
1164+
if (!PP.getHeaderSearchInfo()
1165+
.getHeaderSearchOpts()
1166+
.ModulesSkipDiagnosticOptions) {
11641167
#define DIAGOPT(Name, Bits, Default) Record.push_back(DiagOpts.Name);
11651168
#define ENUM_DIAGOPT(Name, Type, Bits, Default) \
11661169
Record.push_back(static_cast<unsigned>(DiagOpts.get##Name()));
@@ -1175,6 +1178,7 @@ ASTFileSignature ASTWriter::writeUnhashedControlBlock(Preprocessor &PP,
11751178
// are generally transient files and will almost always be overridden.
11761179
Stream.EmitRecord(DIAGNOSTIC_OPTIONS, Record);
11771180
Record.clear();
1181+
}
11781182

11791183
// Header search paths.
11801184
Record.clear();

clang/lib/Tooling/DependencyScanning/ScanAndUpdateArgs.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,15 +36,20 @@ void tooling::dependencies::configureInvocationForCaching(
3636
CI.getCodeGenOpts().CoverageNotesFile.clear();
3737
}
3838

39+
HeaderSearchOptions &HSOpts = CI.getHeaderSearchOpts();
40+
// Avoid writing potentially volatile diagnostic options into pcms.
41+
HSOpts.ModulesSkipDiagnosticOptions = true;
42+
3943
// "Fix" the CAS options.
4044
auto &FileSystemOpts = CI.getFileSystemOpts();
4145
if (ProduceIncludeTree) {
4246
FrontendOpts.CASIncludeTreeID = std::move(RootID);
4347
FrontendOpts.Inputs.clear();
4448
FrontendOpts.ModuleMapFiles.clear();
45-
HeaderSearchOptions &HSOpts = CI.getHeaderSearchOpts();
4649
HeaderSearchOptions OriginalHSOpts;
4750
std::swap(HSOpts, OriginalHSOpts);
51+
HSOpts.ModulesSkipDiagnosticOptions =
52+
OriginalHSOpts.ModulesSkipDiagnosticOptions;
4853
// Preserve sysroot path to accommodate lookup for 'SDKSettings.json' during
4954
// availability checking.
5055
HSOpts.Sysroot = std::move(OriginalHSOpts.Sysroot);

clang/test/CAS/cached-diagnostics.c

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,10 +54,33 @@
5454
// RUN: %clang @%t/t2.rsp 2> %t/cached-diags2.txt
5555
// RUN: diff -u %t/regular-diags2.txt %t/cached-diags2.txt
5656

57+
// RUN: %clang -cc1depscan -fdepscan=inline -fdepscan-include-tree -o %t/terr.rsp -cc1-args \
58+
// RUN: -cc1 -triple x86_64-apple-macos12 -fcas-path %t/cas -fdepscan-prefix-map=%t/src=/^src \
59+
// RUN: -emit-obj %t/src/main.c -o %t/out/output.o -I %t/src/inc -Rcompile-job-cache -DERROR
60+
61+
// RUN: not %clang @%t/terr.rsp -ferror-limit 1 2> %t/diags_error1.txt
62+
// RUN: FileCheck %s -check-prefix=ERROR1 -input-file %t/diags_error1.txt
63+
64+
// ERROR1: error: E1
65+
// ERROR1-NOT: error:
66+
// ERROR1: fatal error: too many errors emitted
67+
68+
// RUN: not %clang @%t/terr.rsp -ferror-limit 2 2> %t/diags_error2.txt
69+
// RUN: FileCheck %s -check-prefix=ERROR2 -input-file %t/diags_error2.txt
70+
71+
// ERROR2: error: E1
72+
// ERROR2: error: E2
73+
// ERROR2-NOT: error:
74+
5775
//--- main.c
5876

5977
#include "t1.h"
6078

79+
#ifdef ERROR
80+
#error E1
81+
#error E2
82+
#endif
83+
6184
//--- inc/t1.h
6285

6386
#warning some warning
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
// RUN: rm -rf %t
2+
// RUN: split-file %s %t
3+
// RUN: sed "s|DIR|%/t|g" %t/cdb.json.template > %t/cdb.json
4+
5+
// RUN: clang-scan-deps -compilation-database %t/cdb.json \
6+
// RUN: -format experimental-include-tree-full -cas-path %t/cas > %t/deps.json
7+
8+
// RUN: %deps-to-rsp %t/deps.json --module-name Mod > %t/Mod.rsp
9+
10+
// RUN: %clang @%t/Mod.rsp
11+
// RUN: %clang @%t/Mod.rsp -fmessage-length=8
12+
// RUN: %clang @%t/Mod.rsp -fcolor-diagnostics
13+
// RUN: %clang @%t/Mod.rsp -ferror-limit 1
14+
15+
//--- cdb.json.template
16+
[{
17+
"file": "DIR/tu.c",
18+
"directory": "DIR",
19+
"command": "clang -Xclang -fcache-disable-replay -fsyntax-only DIR/tu.c -fmodules -fimplicit-modules -fimplicit-module-maps -fmodules-cache-path=DIR/module-cache"
20+
}]
21+
22+
//--- module.modulemap
23+
module Mod { header "Mod.h" }
24+
25+
//--- Mod.h
26+
27+
//--- tu.c
28+
#include "Mod.h"

0 commit comments

Comments
 (0)