mirror of https://github.com/microsoft/clang.git
Basic/Diagnostics: Rewrite DiagnosticIDs::getDiagnosticLevel completely to be straighter line code, use the new DiagnosticMappingInfo flags, and eliminate the odd MAP_WARNING_NO_WERROR and friend mappings.
- This fixes a host of obscure bugs with regards to how warning mapping options composed with one another, and I believe makes the code substantially easier to read and reason about. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@140770 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
a5e41333b0
commit
be1aa41027
|
@ -65,17 +65,7 @@ namespace clang {
|
||||||
MAP_IGNORE = 1, //< Map this diagnostic to nothing, ignore it.
|
MAP_IGNORE = 1, //< Map this diagnostic to nothing, ignore it.
|
||||||
MAP_WARNING = 2, //< Map this diagnostic to a warning.
|
MAP_WARNING = 2, //< Map this diagnostic to a warning.
|
||||||
MAP_ERROR = 3, //< Map this diagnostic to an error.
|
MAP_ERROR = 3, //< Map this diagnostic to an error.
|
||||||
MAP_FATAL = 4, //< Map this diagnostic to a fatal error.
|
MAP_FATAL = 4 //< Map this diagnostic to a fatal error.
|
||||||
|
|
||||||
/// Map this diagnostic to "warning", but make it immune to -Werror. This
|
|
||||||
/// happens when you specify -Wno-error=foo.
|
|
||||||
MAP_WARNING_NO_WERROR = 5,
|
|
||||||
/// Map this diagnostic to "warning", but make it immune to
|
|
||||||
/// -Wno-system-headers.
|
|
||||||
MAP_WARNING_SHOW_IN_SYSTEM_HEADER = 6,
|
|
||||||
/// Map this diagnostic to "error", but make it immune to -Wfatal-errors.
|
|
||||||
/// This happens for -Wno-fatal-errors=foo.
|
|
||||||
MAP_ERROR_NO_WFATAL = 7
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -257,7 +257,10 @@ bool DiagnosticsEngine::setDiagnosticGroupWarningAsError(StringRef Group,
|
||||||
DiagnosticMappingInfo &Info = GetCurDiagState()->getOrAddMappingInfo(
|
DiagnosticMappingInfo &Info = GetCurDiagState()->getOrAddMappingInfo(
|
||||||
GroupDiags[i]);
|
GroupDiags[i]);
|
||||||
|
|
||||||
Info.setMapping(diag::MAP_WARNING_NO_WERROR);
|
if (Info.getMapping() == diag::MAP_ERROR ||
|
||||||
|
Info.getMapping() == diag::MAP_FATAL)
|
||||||
|
Info.setMapping(diag::MAP_WARNING);
|
||||||
|
|
||||||
Info.setNoWarningAsError(true);
|
Info.setNoWarningAsError(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -284,7 +287,9 @@ bool DiagnosticsEngine::setDiagnosticGroupErrorAsFatal(StringRef Group,
|
||||||
DiagnosticMappingInfo &Info = GetCurDiagState()->getOrAddMappingInfo(
|
DiagnosticMappingInfo &Info = GetCurDiagState()->getOrAddMappingInfo(
|
||||||
GroupDiags[i]);
|
GroupDiags[i]);
|
||||||
|
|
||||||
Info.setMapping(diag::MAP_ERROR_NO_WFATAL);
|
if (Info.getMapping() == diag::MAP_FATAL)
|
||||||
|
Info.setMapping(diag::MAP_ERROR);
|
||||||
|
|
||||||
Info.setNoErrorAsFatal(true);
|
Info.setNoErrorAsFatal(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -194,14 +194,12 @@ static DiagnosticMappingInfo GetDefaultDiagMappingInfo(unsigned DiagID) {
|
||||||
if (StaticInfo->WarnNoWerror) {
|
if (StaticInfo->WarnNoWerror) {
|
||||||
assert(Info.getMapping() == diag::MAP_WARNING &&
|
assert(Info.getMapping() == diag::MAP_WARNING &&
|
||||||
"Unexpected mapping with no-Werror bit!");
|
"Unexpected mapping with no-Werror bit!");
|
||||||
Info.setMapping(diag::MAP_WARNING_NO_WERROR);
|
|
||||||
Info.setNoWarningAsError(true);
|
Info.setNoWarningAsError(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (StaticInfo->WarnShowInSystemHeader) {
|
if (StaticInfo->WarnShowInSystemHeader) {
|
||||||
assert(Info.getMapping() == diag::MAP_WARNING &&
|
assert(Info.getMapping() == diag::MAP_WARNING &&
|
||||||
"Unexpected mapping with show-in-system-header bit!");
|
"Unexpected mapping with show-in-system-header bit!");
|
||||||
Info.setMapping(diag::MAP_WARNING_SHOW_IN_SYSTEM_HEADER);
|
|
||||||
Info.setShowInSystemHeader(true);
|
Info.setShowInSystemHeader(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -533,90 +531,73 @@ DiagnosticIDs::getDiagnosticLevel(unsigned DiagID, unsigned DiagClass,
|
||||||
DiagnosticMappingInfo &MappingInfo = State->getOrAddMappingInfo(
|
DiagnosticMappingInfo &MappingInfo = State->getOrAddMappingInfo(
|
||||||
(diag::kind)DiagID);
|
(diag::kind)DiagID);
|
||||||
|
|
||||||
bool ShouldEmitInSystemHeader = false;
|
|
||||||
|
|
||||||
switch (MappingInfo.getMapping()) {
|
switch (MappingInfo.getMapping()) {
|
||||||
default: llvm_unreachable("Unknown mapping!");
|
default: llvm_unreachable("Unknown mapping!");
|
||||||
case diag::MAP_IGNORE:
|
case diag::MAP_IGNORE:
|
||||||
if (Diag.EnableAllWarnings) {
|
Result = DiagnosticIDs::Ignored;
|
||||||
// Leave the warning disabled if it was explicitly ignored.
|
break;
|
||||||
if (MappingInfo.isUser())
|
case diag::MAP_WARNING:
|
||||||
return DiagnosticIDs::Ignored;
|
Result = DiagnosticIDs::Warning;
|
||||||
|
|
||||||
Result = Diag.WarningsAsErrors ? DiagnosticIDs::Error
|
|
||||||
: DiagnosticIDs::Warning;
|
|
||||||
}
|
|
||||||
// Otherwise, ignore this diagnostic unless this is an extension diagnostic
|
|
||||||
// and we're mapping them onto warnings or errors.
|
|
||||||
else if (!isBuiltinExtensionDiag(DiagID) || // Not an extension
|
|
||||||
Diag.ExtBehavior == DiagnosticsEngine::Ext_Ignore || // Ext ignored
|
|
||||||
MappingInfo.isUser()) { // User explicitly mapped it.
|
|
||||||
return DiagnosticIDs::Ignored;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
Result = DiagnosticIDs::Warning;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Diag.ExtBehavior == DiagnosticsEngine::Ext_Error)
|
|
||||||
Result = DiagnosticIDs::Error;
|
|
||||||
if (Result == DiagnosticIDs::Error && Diag.ErrorsAsFatal)
|
|
||||||
Result = DiagnosticIDs::Fatal;
|
|
||||||
break;
|
break;
|
||||||
case diag::MAP_ERROR:
|
case diag::MAP_ERROR:
|
||||||
Result = DiagnosticIDs::Error;
|
Result = DiagnosticIDs::Error;
|
||||||
if (Diag.ErrorsAsFatal)
|
|
||||||
Result = DiagnosticIDs::Fatal;
|
|
||||||
break;
|
break;
|
||||||
case diag::MAP_FATAL:
|
case diag::MAP_FATAL:
|
||||||
Result = DiagnosticIDs::Fatal;
|
Result = DiagnosticIDs::Fatal;
|
||||||
break;
|
break;
|
||||||
case diag::MAP_WARNING_SHOW_IN_SYSTEM_HEADER:
|
|
||||||
ShouldEmitInSystemHeader = true;
|
|
||||||
// continue as MAP_WARNING.
|
|
||||||
case diag::MAP_WARNING:
|
|
||||||
// If warnings are globally mapped to ignore or error, do it.
|
|
||||||
if (Diag.IgnoreAllWarnings)
|
|
||||||
return DiagnosticIDs::Ignored;
|
|
||||||
|
|
||||||
Result = DiagnosticIDs::Warning;
|
|
||||||
|
|
||||||
// If this is an extension diagnostic and we're in -pedantic-error mode, and
|
|
||||||
// if the user didn't explicitly map it, upgrade to an error.
|
|
||||||
if (Diag.ExtBehavior == DiagnosticsEngine::Ext_Error &&
|
|
||||||
!MappingInfo.isUser() &&
|
|
||||||
isBuiltinExtensionDiag(DiagID))
|
|
||||||
Result = DiagnosticIDs::Error;
|
|
||||||
|
|
||||||
if (Diag.WarningsAsErrors)
|
|
||||||
Result = DiagnosticIDs::Error;
|
|
||||||
if (Result == DiagnosticIDs::Error && Diag.ErrorsAsFatal)
|
|
||||||
Result = DiagnosticIDs::Fatal;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case diag::MAP_WARNING_NO_WERROR:
|
|
||||||
// Diagnostics specified with -Wno-error=foo should be set to warnings, but
|
|
||||||
// not be adjusted by -Werror or -pedantic-errors.
|
|
||||||
Result = DiagnosticIDs::Warning;
|
|
||||||
|
|
||||||
// If warnings are globally mapped to ignore or error, do it.
|
|
||||||
if (Diag.IgnoreAllWarnings)
|
|
||||||
return DiagnosticIDs::Ignored;
|
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
case diag::MAP_ERROR_NO_WFATAL:
|
|
||||||
// Diagnostics specified as -Wno-fatal-error=foo should be errors, but
|
|
||||||
// unaffected by -Wfatal-errors.
|
|
||||||
Result = DiagnosticIDs::Error;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Okay, we're about to return this as a "diagnostic to emit" one last check:
|
// Upgrade ignored diagnostics if -Weverything is enabled.
|
||||||
// if this is any sort of extension warning, and if we're in an __extension__
|
if (Diag.EnableAllWarnings && Result == DiagnosticIDs::Ignored &&
|
||||||
// block, silence it.
|
!MappingInfo.isUser())
|
||||||
if (Diag.AllExtensionsSilenced && isBuiltinExtensionDiag(DiagID))
|
Result = DiagnosticIDs::Warning;
|
||||||
|
|
||||||
|
// Ignore any kind of extension diagnostics inside __extension__ blocks.
|
||||||
|
bool IsExtensionDiag = isBuiltinExtensionDiag(DiagID);
|
||||||
|
if (Diag.AllExtensionsSilenced && IsExtensionDiag)
|
||||||
return DiagnosticIDs::Ignored;
|
return DiagnosticIDs::Ignored;
|
||||||
|
|
||||||
|
// For extension diagnostics that haven't been explicitly mapped, check if we
|
||||||
|
// should upgrade the diagnostic.
|
||||||
|
if (IsExtensionDiag && !MappingInfo.isUser()) {
|
||||||
|
switch (Diag.ExtBehavior) {
|
||||||
|
case DiagnosticsEngine::Ext_Ignore:
|
||||||
|
break;
|
||||||
|
case DiagnosticsEngine::Ext_Warn:
|
||||||
|
// Upgrade ignored diagnostics to warnings.
|
||||||
|
if (Result == DiagnosticIDs::Ignored)
|
||||||
|
Result = DiagnosticIDs::Warning;
|
||||||
|
break;
|
||||||
|
case DiagnosticsEngine::Ext_Error:
|
||||||
|
// Upgrade ignored or warning diagnostics to errors.
|
||||||
|
if (Result == DiagnosticIDs::Ignored || Result == DiagnosticIDs::Warning)
|
||||||
|
Result = DiagnosticIDs::Error;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// At this point, ignored errors can no longer be upgraded.
|
||||||
|
if (Result == DiagnosticIDs::Ignored)
|
||||||
|
return Result;
|
||||||
|
|
||||||
|
// Honor -w, which is lower in priority than pedantic-errors, but higher than
|
||||||
|
// -Werror.
|
||||||
|
if (Result == DiagnosticIDs::Warning && Diag.IgnoreAllWarnings)
|
||||||
|
return DiagnosticIDs::Ignored;
|
||||||
|
|
||||||
|
// If -Werror is enabled, map warnings to errors unless explicitly disabled.
|
||||||
|
if (Result == DiagnosticIDs::Warning) {
|
||||||
|
if (Diag.WarningsAsErrors && !MappingInfo.hasNoWarningAsError())
|
||||||
|
Result = DiagnosticIDs::Error;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If -Wfatal-errors is enabled, map errors to fatal unless explicity
|
||||||
|
// disabled.
|
||||||
|
if (Result == DiagnosticIDs::Error) {
|
||||||
|
if (Diag.ErrorsAsFatal && !MappingInfo.hasNoErrorAsFatal())
|
||||||
|
Result = DiagnosticIDs::Fatal;
|
||||||
|
}
|
||||||
|
|
||||||
// If we are in a system header, we ignore it.
|
// If we are in a system header, we ignore it.
|
||||||
// We also want to ignore extensions and warnings in -Werror and
|
// We also want to ignore extensions and warnings in -Werror and
|
||||||
// -pedantic-errors modes, which *map* warnings/extensions to errors.
|
// -pedantic-errors modes, which *map* warnings/extensions to errors.
|
||||||
|
@ -624,7 +605,7 @@ DiagnosticIDs::getDiagnosticLevel(unsigned DiagID, unsigned DiagClass,
|
||||||
DiagClass != CLASS_ERROR &&
|
DiagClass != CLASS_ERROR &&
|
||||||
// Custom diagnostics always are emitted in system headers.
|
// Custom diagnostics always are emitted in system headers.
|
||||||
DiagID < diag::DIAG_UPPER_LIMIT &&
|
DiagID < diag::DIAG_UPPER_LIMIT &&
|
||||||
!ShouldEmitInSystemHeader &&
|
!MappingInfo.hasShowInSystemHeader() &&
|
||||||
Diag.SuppressSystemWarnings &&
|
Diag.SuppressSystemWarnings &&
|
||||||
Loc.isValid() &&
|
Loc.isValid() &&
|
||||||
Diag.getSourceManager().isInSystemHeader(
|
Diag.getSourceManager().isInSystemHeader(
|
||||||
|
|
|
@ -15,4 +15,4 @@ void tf() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Allowed by GNU extension
|
// Allowed by GNU extension
|
||||||
int a4[] = {}; // expected-warning {{zero size arrays}}
|
int a4[] = {}; // expected-error {{zero size arrays}}
|
||||||
|
|
|
@ -2,9 +2,6 @@
|
||||||
// become errors.
|
// become errors.
|
||||||
//
|
//
|
||||||
// RUN: %clang_cc1 -verify -Weverything -pedantic-errors %s
|
// RUN: %clang_cc1 -verify -Weverything -pedantic-errors %s
|
||||||
//
|
|
||||||
// FIXME: This is currently broken.
|
|
||||||
// XFAIL: *
|
|
||||||
|
|
||||||
int f0(int, unsigned);
|
int f0(int, unsigned);
|
||||||
int f0(int x, unsigned y) {
|
int f0(int x, unsigned y) {
|
||||||
|
|
|
@ -1,8 +1,5 @@
|
||||||
// Check that -w has lower priority than -pedantic-errors.
|
// Check that -w has lower priority than -pedantic-errors.
|
||||||
// RUN: %clang_cc1 -verify -pedantic-errors -w %s
|
// RUN: %clang_cc1 -verify -pedantic-errors -w %s
|
||||||
//
|
|
||||||
// FIXME: We currently get this wrong.
|
|
||||||
// XFAIL: *
|
|
||||||
|
|
||||||
void f0() { f1(); } // expected-error {{implicit declaration of function}}
|
void f0() { f1(); } // expected-error {{implicit declaration of function}}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
// RUN: %clang_cc1 -verify -Wno-error=sign-compare %s
|
||||||
|
// RUN: %clang_cc1 -verify -Wsign-compare -w -Wno-error=sign-compare %s
|
||||||
|
|
||||||
|
int f0(int x, unsigned y) {
|
||||||
|
return x < y;
|
||||||
|
}
|
Loading…
Reference in New Issue