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
}

Reply via email to