https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104216
Bug ID: 104216 Summary: -w overrides #pragma GCC diagnostic which overrides -Werror Product: gcc Version: 12.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: driver Assignee: unassigned at gcc dot gnu.org Reporter: msebor at gcc dot gnu.org Target Milestone: --- In the Warning options section the manual says this about -w and -Werror: -w Inhibit all warning messages. -Werror Make all warnings into errors. But then in the Diagnostic Pragmas section it says that GCC allows the user to selectively enable or disable certain types of diagnostics, and change the kind of the diagnostic. This can be read in two ways: either 1) -w (and -Werror) override #pragma GCC diagnostic settings, suppressing both warnings and errors or (for -Werror, turning warnings, either disabled or suppressed by the pragma, into errors), or 2) the diagnostic pragmas override the command line option(s). If (1) was the intended reading then it would seem natural to also expect -Werror to have a similar effect, but it of course doesn't. If it did, that would make the diagnostic pragmas useless in the most common case. With that, I'd expect the more specific #pragma to take precedence over the more general -w, similarly to how the #pragma overrides -Werror on the command line. But that's not how it works, either in GCC or in Clang. -w seems to take precedence over the pragmas while -Werror is overridden by them. Either way it's supposed to work, it would be nice to document what users should expect. A test case: $ cat a.c && gcc -O2 -S -Wall -w a.c extern char a[3]; #pragma GCC diagnostic error "-Warray-bounds" #pragma GCC diagnostic error "-Wstringop-overflow" #pragma GCC diagnostic error "-Wuninitialized" int f (void) { a[3] = 0; // missing -Warray-bounds } void g (void) { __builtin_memset (a + 1, 0, 3); // missing -Wstringop-overflow } int h (void) { int a[3]; return a[1]; // missing -Wuninitalized }