summaryrefslogtreecommitdiffstats
path: root/clang
diff options
context:
space:
mode:
Diffstat (limited to 'clang')
-rw-r--r--clang/include/clang/Basic/Diagnostic.h31
-rw-r--r--clang/lib/Basic/Diagnostic.cpp23
-rw-r--r--clang/tools/clang-cc/Warnings.cpp66
3 files changed, 54 insertions, 66 deletions
diff --git a/clang/include/clang/Basic/Diagnostic.h b/clang/include/clang/Basic/Diagnostic.h
index 99251709aa9..b877366520d 100644
--- a/clang/include/clang/Basic/Diagnostic.h
+++ b/clang/include/clang/Basic/Diagnostic.h
@@ -67,14 +67,9 @@ namespace clang {
MAP_ERROR = 3, //< Map this diagnostic to an error.
MAP_FATAL = 4, //< Map this diagnostic to a fatal error.
- /// Map this diagnostic to "warning", but make it immune to
- /// -pedantic-errors. This happens when you specify -Wfoo for an
- /// extension warning.
- MAP_WARNING_NO_PEDANTIC_ERROR = 5,
-
- /// Map this diagnostic to "warning", but make it immune to -Werror and
- /// -pedantic-errors. This happens when you specify -Wno-error=foo.
- MAP_WARNING_NO_WERROR = 6
+ /// Map this diagnostic to "warning", but make it immune to -Werror. This
+ /// happens when you specify -Wno-error=foo.
+ MAP_WARNING_NO_WERROR = 5
};
}
@@ -145,6 +140,12 @@ public:
Ignored, Note, Warning, Error, Fatal
};
+ /// ExtensionHandling - How do we handle otherwise-unmapped extension? This
+ /// is controlled by -pedantic and -pedantic-errors.
+ enum ExtensionHandling {
+ Ext_Ignore, Ext_Warn, Ext_Error
+ };
+
enum ArgumentKind {
ak_std_string, // std::string
ak_c_string, // const char *
@@ -158,9 +159,10 @@ public:
private:
unsigned char AllExtensionsSilenced; // Used by __extension__
- bool IgnoreAllWarnings; // Ignore all warnings: -w
- bool WarningsAsErrors; // Treat warnings like errors:
- bool SuppressSystemWarnings;// Suppress warnings in system headers.
+ bool IgnoreAllWarnings; // Ignore all warnings: -w
+ bool WarningsAsErrors; // Treat warnings like errors:
+ bool SuppressSystemWarnings; // Suppress warnings in system headers.
+ ExtensionHandling ExtBehavior; // Map extensions onto warnings or errors?
DiagnosticClient *Client;
/// DiagMappings - Mapping information for diagnostics. Mapping info is
@@ -226,6 +228,13 @@ public:
void setSuppressSystemWarnings(bool Val) { SuppressSystemWarnings = Val; }
bool getSuppressSystemWarnings() const { return SuppressSystemWarnings; }
+ /// setExtensionHandlingBehavior - This controls whether otherwise-unmapped
+ /// extension diagnostics are mapped onto ignore/warning/error. This
+ /// corresponds to the GCC -pedantic and -pedantic-errors option.
+ void setExtensionHandlingBehavior(ExtensionHandling H) {
+ ExtBehavior = H;
+ }
+
/// AllExtensionsSilenced - This is a counter bumped when an __extension__
/// block is encountered. When non-zero, all extension diagnostics are
/// entirely silenced, no matter how they are mapped.
diff --git a/clang/lib/Basic/Diagnostic.cpp b/clang/lib/Basic/Diagnostic.cpp
index 6b7f732b3f0..31f56e99bf4 100644
--- a/clang/lib/Basic/Diagnostic.cpp
+++ b/clang/lib/Basic/Diagnostic.cpp
@@ -262,6 +262,7 @@ Diagnostic::Diagnostic(DiagnosticClient *client) : Client(client) {
IgnoreAllWarnings = false;
WarningsAsErrors = false;
SuppressSystemWarnings = false;
+ ExtBehavior = Ext_Ignore;
ErrorOccurred = false;
FatalErrorOccurred = false;
@@ -371,7 +372,15 @@ Diagnostic::getDiagnosticLevel(unsigned DiagID, unsigned DiagClass) const {
switch (MappingInfo & 7) {
default: assert(0 && "Unknown mapping!");
case diag::MAP_IGNORE:
- return Diagnostic::Ignored;
+ // Ignore this, unless this is an extension diagnostic and we're mapping
+ // them onto warnings or errors.
+ if (!isBuiltinExtensionDiag(DiagID) || // Not an extension
+ ExtBehavior == Ext_Ignore || // Extensions ignored anyway
+ (MappingInfo & 8) != 0) // User explicitly mapped it.
+ return Diagnostic::Ignored;
+ Result = Diagnostic::Warning;
+ if (ExtBehavior == Ext_Error) Result = Diagnostic::Error;
+ break;
case diag::MAP_ERROR:
Result = Diagnostic::Error;
break;
@@ -384,9 +393,18 @@ Diagnostic::getDiagnosticLevel(unsigned DiagID, unsigned DiagClass) const {
return Diagnostic::Ignored;
Result = Diagnostic::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 (ExtBehavior == Ext_Error &&
+ (MappingInfo & 8) == 0 &&
+ isBuiltinExtensionDiag(DiagID))
+ Result = Diagnostic::Error;
+
if (WarningsAsErrors)
Result = Diagnostic::Error;
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.
@@ -634,8 +652,7 @@ static bool EvalPluralExpr(unsigned ValNo, const char *Start, const char *End) {
/// {1:form0|%100=[10,20]:form2|%10=[2,4]:form1|:form2}
static void HandlePluralModifier(unsigned ValNo,
const char *Argument, unsigned ArgumentLen,
- llvm::SmallVectorImpl<char> &OutStr)
-{
+ llvm::SmallVectorImpl<char> &OutStr) {
const char *ArgumentEnd = Argument + ArgumentLen;
while (1) {
assert(Argument < ArgumentEnd && "Plural expression didn't match.");
diff --git a/clang/tools/clang-cc/Warnings.cpp b/clang/tools/clang-cc/Warnings.cpp
index 818e7743d87..bab2ab7a140 100644
--- a/clang/tools/clang-cc/Warnings.cpp
+++ b/clang/tools/clang-cc/Warnings.cpp
@@ -65,21 +65,17 @@ static bool WarningOptionCompare(const WarningOption &LHS,
}
static void MapGroupMembers(const WarningOption *Group, diag::Mapping Mapping,
- Diagnostic &Diags,
- llvm::SmallVectorImpl<unsigned short> &ControlledDiags) {
+ Diagnostic &Diags) {
// Option exists, poke all the members of its diagnostic set.
if (const short *Member = Group->Members) {
- for (; *Member != -1; ++Member) {
+ for (; *Member != -1; ++Member)
Diags.setDiagnosticMapping(*Member, Mapping);
- ControlledDiags.push_back(*Member);
- }
}
// Enable/disable all subgroups along with this one.
if (const char *SubGroups = Group->SubGroups) {
for (; *SubGroups != (char)-1; ++SubGroups)
- MapGroupMembers(&OptionTable[(unsigned char)*SubGroups], Mapping,
- Diags, ControlledDiags);
+ MapGroupMembers(&OptionTable[(unsigned char)*SubGroups], Mapping, Diags);
}
}
@@ -87,13 +83,19 @@ bool clang::ProcessWarningOptions(Diagnostic &Diags) {
Diags.setSuppressSystemWarnings(true); // Default to -Wno-system-headers
Diags.setIgnoreAllWarnings(OptNoWarnings);
+ // If -pedantic or -pedantic-errors was specified, then we want to map all
+ // extension diagnostics onto WARNING or ERROR unless the user has futz'd
+ // around with them explicitly.
+ if (OptPedanticErrors)
+ Diags.setExtensionHandlingBehavior(Diagnostic::Ext_Error);
+ else if (OptPedantic)
+ Diags.setExtensionHandlingBehavior(Diagnostic::Ext_Warn);
+ else
+ Diags.setExtensionHandlingBehavior(Diagnostic::Ext_Ignore);
+
// FIXME: -fdiagnostics-show-option
// FIXME: -Wfatal-errors / -Wfatal-errors=foo
- /// ControlledDiags - Keep track of the options that the user explicitly
- /// poked with -Wfoo, -Wno-foo, or -Werror=foo.
- llvm::SmallVector<unsigned short, 256> ControlledDiags;
-
for (unsigned i = 0, e = OptWarnings.size(); i != e; ++i) {
const std::string &Opt = OptWarnings[i];
const char *OptStart = &Opt[0];
@@ -152,47 +154,7 @@ bool clang::ProcessWarningOptions(Diagnostic &Diags) {
continue;
}
- MapGroupMembers(Found, Mapping, Diags, ControlledDiags);
- }
-
- // If -pedantic or -pedantic-errors was specified, then we want to map all
- // extension diagnostics onto WARNING or ERROR unless the user has futz'd
- // around with them explicitly.
- if (OptPedantic || OptPedanticErrors) {
- // Sort the array of options that has been poked at directly so we can do
- // efficient queries.
- std::sort(ControlledDiags.begin(), ControlledDiags.end());
-
- // Don't worry about iteration off the end down below.
- ControlledDiags.push_back(diag::DIAG_UPPER_LIMIT);
-
- diag::Mapping Mapping =
- OptPedanticErrors ? diag::MAP_ERROR : diag::MAP_WARNING;
-
- // Loop over all of the extension diagnostics. Unless they were explicitly
- // controlled, reset their mapping to Mapping. We walk through the
- // ControlledDiags in parallel with this walk, which is faster than
- // repeatedly binary searching it.
- //
- llvm::SmallVectorImpl<unsigned short>::iterator ControlledDiagsIt =
- ControlledDiags.begin();
-
- // TODO: if it matters, we could make tblgen produce a list of just the
- // extension diags to avoid skipping ones that don't matter.
- for (unsigned short i = 0; i != diag::DIAG_UPPER_LIMIT; ++i) {
- // If this diagnostic was controlled, ignore it.
- if (i == *ControlledDiagsIt) {
- ++ControlledDiagsIt;
- while (i == *ControlledDiagsIt) // ControlledDiags can have dupes.
- ++ControlledDiagsIt;
- // Do not map this diagnostic ID#.
- continue;
- }
-
- // Okay, the user didn't control this ID. If it is an example, map it.
- if (Diagnostic::isBuiltinExtensionDiag(i))
- Diags.setDiagnosticMapping(i, Mapping);
- }
+ MapGroupMembers(Found, Mapping, Diags);
}
return false;
OpenPOWER on IntegriCloud