diff options
-rw-r--r-- | include/clang/Basic/Diagnostic.h | 5 | ||||
-rw-r--r-- | include/clang/Basic/DiagnosticIDs.h | 6 | ||||
-rw-r--r-- | lib/Basic/DiagnosticIDs.cpp | 11 | ||||
-rw-r--r-- | lib/Frontend/TextDiagnosticPrinter.cpp | 14 | ||||
-rw-r--r-- | test/Sema/parentheses.c | 4 |
5 files changed, 32 insertions, 8 deletions
diff --git a/include/clang/Basic/Diagnostic.h b/include/clang/Basic/Diagnostic.h index 19e7c91f53..3fc60d136b 100644 --- a/include/clang/Basic/Diagnostic.h +++ b/include/clang/Basic/Diagnostic.h @@ -474,8 +474,9 @@ public: /// /// \param Loc The source location we are interested in finding out the /// diagnostic state. Can be null in order to query the latest state. - Level getDiagnosticLevel(unsigned DiagID, SourceLocation Loc) const { - return (Level)Diags->getDiagnosticLevel(DiagID, Loc, *this); + Level getDiagnosticLevel(unsigned DiagID, SourceLocation Loc, + diag::Mapping *mapping = 0) const { + return (Level)Diags->getDiagnosticLevel(DiagID, Loc, *this, mapping); } /// Report - Issue the message to the client. @c DiagID is a member of the diff --git a/include/clang/Basic/DiagnosticIDs.h b/include/clang/Basic/DiagnosticIDs.h index b463805698..2b03cae565 100644 --- a/include/clang/Basic/DiagnosticIDs.h +++ b/include/clang/Basic/DiagnosticIDs.h @@ -188,14 +188,16 @@ private: /// \param Loc The source location we are interested in finding out the /// diagnostic state. Can be null in order to query the latest state. DiagnosticIDs::Level getDiagnosticLevel(unsigned DiagID, SourceLocation Loc, - const Diagnostic &Diag) const; + const Diagnostic &Diag, + diag::Mapping *mapping = 0) const; /// getDiagnosticLevel - This is an internal implementation helper used when /// DiagClass is already known. DiagnosticIDs::Level getDiagnosticLevel(unsigned DiagID, unsigned DiagClass, SourceLocation Loc, - const Diagnostic &Diag) const; + const Diagnostic &Diag, + diag::Mapping *mapping = 0) const; /// ProcessDiag - This is the method used to report a diagnostic that is /// finally fully formed. diff --git a/lib/Basic/DiagnosticIDs.cpp b/lib/Basic/DiagnosticIDs.cpp index 8725e7f9c0..553e4c9294 100644 --- a/lib/Basic/DiagnosticIDs.cpp +++ b/lib/Basic/DiagnosticIDs.cpp @@ -288,14 +288,15 @@ const char *DiagnosticIDs::getDescription(unsigned DiagID) const { /// the DiagnosticClient. DiagnosticIDs::Level DiagnosticIDs::getDiagnosticLevel(unsigned DiagID, SourceLocation Loc, - const Diagnostic &Diag) const { + const Diagnostic &Diag, + diag::Mapping *mapping) const { // Handle custom diagnostics, which cannot be mapped. if (DiagID >= diag::DIAG_UPPER_LIMIT) return CustomDiagInfo->getLevel(DiagID); unsigned DiagClass = getBuiltinDiagClass(DiagID); assert(DiagClass != CLASS_NOTE && "Cannot get diagnostic level of a note!"); - return getDiagnosticLevel(DiagID, DiagClass, Loc, Diag); + return getDiagnosticLevel(DiagID, DiagClass, Loc, Diag, mapping); } /// \brief Based on the way the client configured the Diagnostic @@ -307,7 +308,8 @@ DiagnosticIDs::getDiagnosticLevel(unsigned DiagID, SourceLocation Loc, DiagnosticIDs::Level DiagnosticIDs::getDiagnosticLevel(unsigned DiagID, unsigned DiagClass, SourceLocation Loc, - const Diagnostic &Diag) const { + const Diagnostic &Diag, + diag::Mapping *mapping) const { // Specific non-error diagnostics may be mapped to various levels from ignored // to error. Errors can only be mapped to fatal. DiagnosticIDs::Level Result = DiagnosticIDs::Fatal; @@ -323,6 +325,9 @@ DiagnosticIDs::getDiagnosticLevel(unsigned DiagID, unsigned DiagClass, MappingInfo = GetDefaultDiagMapping(DiagID); Diag.setDiagnosticMappingInternal(DiagID, MappingInfo, State, false, false); } + + if (mapping) + *mapping = (diag::Mapping) (MappingInfo & 7); switch (MappingInfo & 7) { default: assert(0 && "Unknown mapping!"); diff --git a/lib/Frontend/TextDiagnosticPrinter.cpp b/lib/Frontend/TextDiagnosticPrinter.cpp index 04c6a68023..084915311d 100644 --- a/lib/Frontend/TextDiagnosticPrinter.cpp +++ b/lib/Frontend/TextDiagnosticPrinter.cpp @@ -905,9 +905,21 @@ void TextDiagnosticPrinter::HandleDiagnostic(Diagnostic::Level Level, std::string OptionName; if (DiagOpts->ShowOptionNames) { + // Was this a warning mapped to an error using -Werror or pragma? + if (Level == Diagnostic::Error && + DiagnosticIDs::isBuiltinWarningOrExtension(Info.getID())) { + diag::Mapping mapping = diag::MAP_IGNORE; + Info.getDiags()->getDiagnosticLevel(Info.getID(), Info.getLocation(), + &mapping); + if (mapping == diag::MAP_WARNING) + OptionName += "-Werror"; + } + if (const char * Opt = DiagnosticIDs::getWarningOptionForDiag(Info.getID())) { - OptionName = "-W"; + if (!OptionName.empty()) + OptionName += ','; + OptionName += "-W"; OptionName += Opt; } else if (Info.getID() == diag::fatal_too_many_errors) { OptionName = "-ferror-limit="; diff --git a/test/Sema/parentheses.c b/test/Sema/parentheses.c index 6d6fa1d4bd..b45d8512f6 100644 --- a/test/Sema/parentheses.c +++ b/test/Sema/parentheses.c @@ -37,3 +37,7 @@ void bitwise_rel(unsigned i) { (void)(i && i || 0); // no warning. (void)(0 || i && i); // no warning. } + +// RUN: %clang_cc1 -fsyntax-only -Wparentheses -Werror -fdiagnostics-show-option %s 2>&1 | FileCheck %s +// CHECK: error: using the result of an assignment as a condition without parentheses [-Werror,-Wparentheses] + |