summaryrefslogtreecommitdiffstats
path: root/clang/lib/Serialization
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/Serialization')
-rw-r--r--clang/lib/Serialization/ASTReader.cpp50
-rw-r--r--clang/lib/Serialization/ASTWriter.cpp7
2 files changed, 49 insertions, 8 deletions
diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp
index e09af28059b..d6bacfe3e09 100644
--- a/clang/lib/Serialization/ASTReader.cpp
+++ b/clang/lib/Serialization/ASTReader.cpp
@@ -5525,18 +5525,54 @@ void ASTReader::ReadPragmaDiagnosticMappings(DiagnosticsEngine &Diag) {
"Invalid data, not enough diag/map pairs");
while (Size--) {
unsigned DiagID = Record[Idx++];
- diag::Severity Map = (diag::Severity)Record[Idx++];
- DiagnosticMapping Mapping = Diag.makeUserMapping(Map, Loc);
- if (Mapping.isPragma() || IncludeNonPragmaStates)
- NewState->setMapping(DiagID, Mapping);
+ unsigned SeverityAndUpgradedFromWarning = Record[Idx++];
+ bool WasUpgradedFromWarning =
+ DiagnosticMapping::deserializeUpgradedFromWarning(
+ SeverityAndUpgradedFromWarning);
+ DiagnosticMapping NewMapping =
+ Diag.makeUserMapping(DiagnosticMapping::deserializeSeverity(
+ SeverityAndUpgradedFromWarning),
+ Loc);
+ if (!NewMapping.isPragma() && !IncludeNonPragmaStates)
+ continue;
+
+ DiagnosticMapping &Mapping = NewState->getOrAddMapping(DiagID);
+
+ // If this mapping was specified as a warning but the severity was
+ // upgraded due to diagnostic settings, simulate the current diagnostic
+ // settings (and use a warning).
+ if (WasUpgradedFromWarning && !Mapping.isErrorOrFatal()) {
+ Mapping = Diag.makeUserMapping(diag::Severity::Warning, Loc);
+ continue;
+ }
+
+ // Use the deserialized mapping verbatim.
+ Mapping = NewMapping;
+ Mapping.setUpgradedFromWarning(WasUpgradedFromWarning);
}
return NewState;
};
// Read the first state.
- auto *FirstState = ReadDiagState(
- F.isModule() ? DiagState() : *Diag.DiagStatesByLoc.CurDiagState,
- SourceLocation(), F.isModule());
+ DiagState *FirstState;
+ if (F.Kind == MK_ImplicitModule) {
+ // Implicitly-built modules are reused with different diagnostic
+ // settings. Use the initial diagnostic state from Diag to simulate this
+ // compilation's diagnostic settings.
+ FirstState = Diag.DiagStatesByLoc.FirstDiagState;
+ DiagStates.push_back(FirstState);
+
+ // Skip the initial diagnostic state from the serialized module.
+ assert(Record[0] == 0 &&
+ "Invalid data, unexpected backref in initial state");
+ Idx = 2 + Record[1] * 2;
+ assert(Idx < Record.size() &&
+ "Invalid data, not enough state change pairs in initial state");
+ } else {
+ FirstState = ReadDiagState(
+ F.isModule() ? DiagState() : *Diag.DiagStatesByLoc.CurDiagState,
+ SourceLocation(), F.isModule());
+ }
// Read the state transitions.
unsigned NumLocations = Record[Idx++];
diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp
index ffcad78f295..7dd2ca302ca 100644
--- a/clang/lib/Serialization/ASTWriter.cpp
+++ b/clang/lib/Serialization/ASTWriter.cpp
@@ -2879,7 +2879,7 @@ void ASTWriter::WritePragmaDiagnosticMappings(const DiagnosticsEngine &Diag,
for (const auto &I : *State) {
if (I.second.isPragma() || IncludeNonPragmaStates) {
Record.push_back(I.first);
- Record.push_back((unsigned)I.second.getSeverity());
+ Record.push_back(I.second.serializeBits());
}
}
// Update the placeholder.
@@ -2913,6 +2913,11 @@ void ASTWriter::WritePragmaDiagnosticMappings(const DiagnosticsEngine &Diag,
Record[NumLocationsIdx] = NumLocations;
// Emit CurDiagStateLoc. Do it last in order to match source order.
+ //
+ // This also protects against a hypothetical corner case with simulating
+ // -Werror settings for implicit modules in the ASTReader, where reading
+ // CurDiagState out of context could change whether warning pragmas are
+ // treated as errors.
AddSourceLocation(Diag.DiagStatesByLoc.CurDiagStateLoc, Record);
AddDiagState(Diag.DiagStatesByLoc.CurDiagState, false);
OpenPOWER on IntegriCloud