summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/Basic/CMakeLists.txt1
-rw-r--r--clang/lib/Basic/Warnings.cpp (renamed from clang/lib/Frontend/Warnings.cpp)5
-rw-r--r--clang/lib/Frontend/CMakeLists.txt1
-rw-r--r--clang/lib/Frontend/FrontendActions.cpp19
-rw-r--r--clang/lib/Serialization/ASTReader.cpp131
5 files changed, 144 insertions, 13 deletions
diff --git a/clang/lib/Basic/CMakeLists.txt b/clang/lib/Basic/CMakeLists.txt
index 0448fdb0d41..0df82b3bc90 100644
--- a/clang/lib/Basic/CMakeLists.txt
+++ b/clang/lib/Basic/CMakeLists.txt
@@ -25,6 +25,7 @@ add_clang_library(clangBasic
Version.cpp
VersionTuple.cpp
VirtualFileSystem.cpp
+ Warnings.cpp
)
# Determine Subversion revision.
diff --git a/clang/lib/Frontend/Warnings.cpp b/clang/lib/Basic/Warnings.cpp
index 767096a1c99..b09e69aeca6 100644
--- a/clang/lib/Frontend/Warnings.cpp
+++ b/clang/lib/Basic/Warnings.cpp
@@ -20,12 +20,9 @@
// Given a warning option 'foo', the following are valid:
// -Wfoo, -Wno-foo, -Werror=foo, -Wfatal-errors=foo
//
-#include "clang/Frontend/Utils.h"
+#include "clang/Basic/AllDiagnostics.h"
#include "clang/Basic/Diagnostic.h"
#include "clang/Basic/DiagnosticOptions.h"
-#include "clang/Frontend/FrontendDiagnostic.h"
-#include "clang/Lex/LexDiagnostic.h"
-#include "clang/Sema/SemaDiagnostic.h"
#include <algorithm>
#include <cstring>
#include <utility>
diff --git a/clang/lib/Frontend/CMakeLists.txt b/clang/lib/Frontend/CMakeLists.txt
index f1c789778f1..b67e0aed24c 100644
--- a/clang/lib/Frontend/CMakeLists.txt
+++ b/clang/lib/Frontend/CMakeLists.txt
@@ -32,7 +32,6 @@ add_clang_library(clangFrontend
TextDiagnosticBuffer.cpp
TextDiagnosticPrinter.cpp
VerifyDiagnosticConsumer.cpp
- Warnings.cpp
DEPENDS
ClangDriverOptions
diff --git a/clang/lib/Frontend/FrontendActions.cpp b/clang/lib/Frontend/FrontendActions.cpp
index 3d65ae32c01..a8df7fd1cb8 100644
--- a/clang/lib/Frontend/FrontendActions.cpp
+++ b/clang/lib/Frontend/FrontendActions.cpp
@@ -459,6 +459,25 @@ namespace {
return false;
}
+ virtual bool
+ ReadDiagnosticOptions(IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts,
+ bool Complain) override {
+ Out.indent(2) << "Diagnostic options:\n";
+#define DIAGOPT(Name, Bits, Default) DUMP_BOOLEAN(DiagOpts->Name, #Name);
+#define ENUM_DIAGOPT(Name, Type, Bits, Default) \
+ Out.indent(4) << #Name << ": " << DiagOpts->get##Name() << "\n";
+#define VALUE_DIAGOPT(Name, Bits, Default) \
+ Out.indent(4) << #Name << ": " << DiagOpts->Name << "\n";
+#include "clang/Basic/DiagnosticOptions.def"
+
+ Out.indent(4) << "Warning options:\n";
+ for (const std::string &Warning : DiagOpts->Warnings) {
+ Out.indent(6) << "-W" << Warning << "\n";
+ }
+
+ return false;
+ }
+
bool ReadHeaderSearchOptions(const HeaderSearchOptions &HSOpts,
bool Complain) override {
Out.indent(2) << "Header search options:\n";
diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp
index 834917de1d4..c6aec4592ba 100644
--- a/clang/lib/Serialization/ASTReader.cpp
+++ b/clang/lib/Serialization/ASTReader.cpp
@@ -29,6 +29,7 @@
#include "clang/Basic/TargetOptions.h"
#include "clang/Basic/Version.h"
#include "clang/Basic/VersionTuple.h"
+#include "clang/Frontend/Utils.h"
#include "clang/Lex/HeaderSearch.h"
#include "clang/Lex/HeaderSearchOptions.h"
#include "clang/Lex/MacroInfo.h"
@@ -90,7 +91,7 @@ ChainedASTReaderListener::ReadTargetOptions(const TargetOptions &TargetOpts,
Second->ReadTargetOptions(TargetOpts, Complain);
}
bool ChainedASTReaderListener::ReadDiagnosticOptions(
- const DiagnosticOptions &DiagOpts, bool Complain) {
+ IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts, bool Complain) {
return First->ReadDiagnosticOptions(DiagOpts, Complain) ||
Second->ReadDiagnosticOptions(DiagOpts, Complain);
}
@@ -291,6 +292,120 @@ namespace {
DeclsMap;
}
+static bool checkDiagnosticGroupMappings(DiagnosticsEngine &StoredDiags,
+ DiagnosticsEngine &Diags,
+ bool Complain) {
+ typedef DiagnosticsEngine::Level Level;
+
+ // Check current mappings for new -Werror mappings, and the stored mappings
+ // for cases that were explicitly mapped to *not* be errors that are now
+ // errors because of options like -Werror.
+ DiagnosticsEngine *MappingSources[] = { &Diags, &StoredDiags };
+
+ for (DiagnosticsEngine *MappingSource : MappingSources) {
+ for (auto DiagIDMappingPair : MappingSource->getDiagnosticMappings()) {
+ diag::kind DiagID = DiagIDMappingPair.first;
+ Level CurLevel = Diags.getDiagnosticLevel(DiagID, SourceLocation());
+ if (CurLevel < DiagnosticsEngine::Error)
+ continue; // not significant
+ Level StoredLevel =
+ StoredDiags.getDiagnosticLevel(DiagID, SourceLocation());
+ if (StoredLevel < DiagnosticsEngine::Error) {
+ if (Complain)
+ Diags.Report(diag::err_pch_diagopt_mismatch) << "-Werror=" +
+ Diags.getDiagnosticIDs()->getWarningOptionForDiag(DiagID).str();
+ return true;
+ }
+ }
+ }
+
+ return false;
+}
+
+static DiagnosticsEngine::ExtensionHandling
+isExtHandlingFromDiagsError(DiagnosticsEngine &Diags) {
+ DiagnosticsEngine::ExtensionHandling Ext =
+ Diags.getExtensionHandlingBehavior();
+ if (Ext == DiagnosticsEngine::Ext_Warn && Diags.getWarningsAsErrors())
+ Ext = DiagnosticsEngine::Ext_Error;
+ return Ext;
+}
+
+static bool checkDiagnosticMappings(DiagnosticsEngine &StoredDiags,
+ DiagnosticsEngine &Diags,
+ bool IsSystem, bool Complain) {
+ // Top-level options
+ if (IsSystem) {
+ if (Diags.getSuppressSystemWarnings())
+ return false;
+ // If -Wsystem-headers was not enabled before, be conservative
+ if (StoredDiags.getSuppressSystemWarnings()) {
+ if (Complain)
+ Diags.Report(diag::err_pch_diagopt_mismatch) << "-Wsystem-headers";
+ return true;
+ }
+ }
+
+ if (Diags.getWarningsAsErrors() && !StoredDiags.getWarningsAsErrors()) {
+ if (Complain)
+ Diags.Report(diag::err_pch_diagopt_mismatch) << "-Werror";
+ return true;
+ }
+
+ if (Diags.getWarningsAsErrors() && Diags.getEnableAllWarnings() &&
+ !StoredDiags.getEnableAllWarnings()) {
+ if (Complain)
+ Diags.Report(diag::err_pch_diagopt_mismatch) << "-Weverything -Werror";
+ return true;
+ }
+
+ if (isExtHandlingFromDiagsError(Diags) &&
+ !isExtHandlingFromDiagsError(StoredDiags)) {
+ if (Complain)
+ Diags.Report(diag::err_pch_diagopt_mismatch) << "-pedantic-errors";
+ return true;
+ }
+
+ return checkDiagnosticGroupMappings(StoredDiags, Diags, Complain);
+}
+
+bool PCHValidator::ReadDiagnosticOptions(
+ IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts, bool Complain) {
+ DiagnosticsEngine &ExistingDiags = PP.getDiagnostics();
+ IntrusiveRefCntPtr<DiagnosticIDs> DiagIDs(ExistingDiags.getDiagnosticIDs());
+ IntrusiveRefCntPtr<DiagnosticsEngine> Diags(
+ new DiagnosticsEngine(DiagIDs, DiagOpts.getPtr()));
+ // This should never fail, because we would have processed these options
+ // before writing them to an ASTFile.
+ ProcessWarningOptions(*Diags, *DiagOpts, /*Report*/false);
+
+ ModuleManager &ModuleMgr = Reader.getModuleManager();
+ assert(ModuleMgr.size() >= 1 && "what ASTFile is this then");
+
+ // If the original import came from a file explicitly generated by the user,
+ // don't check the diagnostic mappings.
+ // FIXME: currently this is approximated by checking whether this is not a
+ // module import.
+ // Note: ModuleMgr.rbegin() may not be the current module, but it must be in
+ // the transitive closure of its imports, since unrelated modules cannot be
+ // imported until after this module finishes validation.
+ ModuleFile *TopImport = *ModuleMgr.rbegin();
+ while (!TopImport->ImportedBy.empty())
+ TopImport = TopImport->ImportedBy[0];
+ if (TopImport->Kind != MK_Module)
+ return false;
+
+ StringRef ModuleName = TopImport->ModuleName;
+ assert(!ModuleName.empty() && "diagnostic options read before module name");
+
+ Module *M = PP.getHeaderSearchInfo().lookupModule(ModuleName);
+ assert(M && "missing module");
+
+ // FIXME: if the diagnostics are incompatible, save a DiagnosticOptions that
+ // contains the union of their flags.
+ return checkDiagnosticMappings(*Diags, ExistingDiags, M->IsSystem, Complain);
+}
+
/// \brief Collect the macro definitions provided by the given preprocessor
/// options.
static void collectMacroDefinitions(const PreprocessorOptions &PPOpts,
@@ -2268,11 +2383,11 @@ ASTReader::ReadControlBlock(ModuleFile &F,
}
case DIAGNOSTIC_OPTIONS: {
- bool Complain = (ClientLoadCapabilities & ARR_ConfigurationMismatch)==0;
+ bool Complain = (ClientLoadCapabilities & ARR_OutOfDate)==0;
if (Listener && &F == *ModuleMgr.begin() &&
ParseDiagnosticOptions(Record, Complain, *Listener) &&
- !DisableValidation && !AllowConfigurationMismatch)
- return ConfigurationMismatch;
+ !DisableValidation)
+ return OutOfDate;
break;
}
@@ -4481,15 +4596,15 @@ bool ASTReader::ParseTargetOptions(const RecordData &Record,
bool ASTReader::ParseDiagnosticOptions(const RecordData &Record, bool Complain,
ASTReaderListener &Listener) {
- DiagnosticOptions DiagOpts;
+ IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts(new DiagnosticOptions);
unsigned Idx = 0;
-#define DIAGOPT(Name, Bits, Default) DiagOpts.Name = Record[Idx++];
+#define DIAGOPT(Name, Bits, Default) DiagOpts->Name = Record[Idx++];
#define ENUM_DIAGOPT(Name, Type, Bits, Default) \
- DiagOpts.set##Name(static_cast<Type>(Record[Idx++]));
+ DiagOpts->set##Name(static_cast<Type>(Record[Idx++]));
#include "clang/Basic/DiagnosticOptions.def"
for (unsigned N = Record[Idx++]; N; --N) {
- DiagOpts.Warnings.push_back(ReadString(Record, Idx));
+ DiagOpts->Warnings.push_back(ReadString(Record, Idx));
}
return Listener.ReadDiagnosticOptions(DiagOpts, Complain);
OpenPOWER on IntegriCloud