Index: clang/lib/Basic/DiagnosticIDs.cpp =================================================================== --- clang/lib/Basic/DiagnosticIDs.cpp +++ clang/lib/Basic/DiagnosticIDs.cpp @@ -457,12 +457,15 @@ if (Result == diag::Severity::Ignored) return Result; - // Honor -w, which is lower in priority than pedantic-errors, but higher than - // -Werror. - // FIXME: Under GCC, this also suppresses warnings that have been mapped to - // errors by -W flags and #pragma diagnostic. - if (Result == diag::Severity::Warning && State->IgnoreAllWarnings) - return diag::Severity::Ignored; + // Honor -w: this disables all messages mapped to Warning severity, and *also* + // any diagnostics which are not Error/Fatal by default (that is, they were + // upgraded by any of the mechanisms available: -Werror, -pedantic, or #pragma + // diagnostic) + if (State->IgnoreAllWarnings) { + if (Result == diag::Severity::Warning || + !isDefaultMappingAsError((diag::kind)DiagID)) + return diag::Severity::Ignored; + } // If -Werror is enabled, map warnings to errors unless explicitly disabled. if (Result == diag::Severity::Warning) { Index: clang/test/Frontend/warning-mapping-2.c =================================================================== --- clang/test/Frontend/warning-mapping-2.c +++ clang/test/Frontend/warning-mapping-2.c @@ -1,5 +1,7 @@ -// Check that -w has lower priority than -pedantic-errors. +// Check that -w takes precedence over -pedantic-errors. // RUN: %clang_cc1 -verify -pedantic-errors -w %s -void f0() { f1(); } // expected-error {{implicit declaration of function}} +// Expect *not* to see a diagnostic for "implicit declaration of function" +// expected-no-diagnostics +void f0() { f1(); } Index: clang/test/Frontend/warning-mapping-4.c =================================================================== --- clang/test/Frontend/warning-mapping-4.c +++ clang/test/Frontend/warning-mapping-4.c @@ -1,5 +1,9 @@ +// Verify that various combinations of flags properly keep the sign-compare +// warning disabled. + // RUN: %clang_cc1 -verify -Wno-error=sign-compare %s // RUN: %clang_cc1 -verify -Wsign-compare -w -Wno-error=sign-compare %s +// RUN: %clang_cc1 -verify -w -Werror=sign-compare %s // expected-no-diagnostics int f0(int x, unsigned y) { Index: clang/test/Frontend/warning-mapping-5.c =================================================================== --- clang/test/Frontend/warning-mapping-5.c +++ clang/test/Frontend/warning-mapping-5.c @@ -1,6 +1,5 @@ -// Check that #pragma diagnostic warning overrides -Werror. This matches GCC's -// original documentation, but not its earlier implementations. -// +// Check that #pragma diagnostic warning overrides -Werror. +// // RUN: %clang_cc1 -verify -Werror %s #pragma clang diagnostic warning "-Wsign-compare" Index: clang/test/Frontend/warning-mapping-6.c =================================================================== --- /dev/null +++ clang/test/Frontend/warning-mapping-6.c @@ -0,0 +1,9 @@ +// Check that "#pragma diagnostic error" is suppressed by -w. +// +// RUN: %clang_cc1 -verify -Werror -w %s + +// expected-no-diagnostics +#pragma gcc diagnostic error "-Wsign-compare" +int f0(int x, unsigned y) { + return x < y; +}