https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71603

            Bug ID: 71603
           Summary: pragma diagnostic pop fails to restore warning level
           Product: gcc
           Version: 7.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c
          Assignee: unassigned at gcc dot gnu.org
          Reporter: msebor at gcc dot gnu.org
  Target Milestone: ---

According to the description of #pragma GCC diagnostic push and #pragma GCC
diagnostic pop in the GCC manual:

Causes GCC to remember the state of the diagnostics as of each push, and
restore to that point at each pop. If a pop has no matching push, the
command-line options are restored.

With that, I would expect the following program to cause exactly two warnings,
one for each of -Wformat and -Wshift-overflow, as mentioned in the comments. 
But GCC issues four diagnostics instead, indicating that the #pragma pop
directive fails to restore the state of the warnings to that at the point of
each corresponding push.

$ cat t.C && /home/msebor/build/gcc-trunk-svn/gcc/xgcc -B
/home/msebor/build/gcc-trunk-svn/gcc -S -xc t.C
void f (const char *s)
{
#pragma GCC diagnostic warning "-Wformat=1"

  __builtin_printf (s, s);   // no -Wformat diagnostic expected

#pragma GCC diagnostic push
#pragma GCC diagnostic warning "-Wformat=2"
  __builtin_printf (s, s);   // -Wformat-nonliteral expected
#pragma GCC diagnostic pop

  __builtin_printf (s, s);   // no diagnostic expected
}

int x;

int g (void)
{
  enum { i = 1 };

#pragma GCC diagnostic warning "-Wshift-overflow=1"

  x = i << 31;   // no -Wshift-overflow expected

#pragma GCC diagnostic push
#pragma GCC diagnostic warning "-Wshift-overflow=2"

  x = i << 31;   // -Wshift-overflow expected

#pragma GCC diagnostic pop
  x = i << 31;   // no warning expected
}
t.C: In function ‘f’:
t.C:9:3: warning: format not a string literal, argument types not checked
[-Wformat-nonliteral]
   __builtin_printf (s, s);   // -Wformat-nonliteral expected
   ^~~~~~~~~~~~~~~~
t.C:12:3: warning: format not a string literal, argument types not checked
[-Wformat-nonliteral]
   __builtin_printf (s, s);   // no diagnostic expected
   ^~~~~~~~~~~~~~~~
t.C: In function ‘g’:
t.C:28:9: warning: result of ‘1 << 31’ requires 33 bits to represent, but ‘int’
only has 32 bits [-Wshift-overflow=]
   x = i << 31;   // -Wshift-overflow expected
         ^~
t.C:31:9: warning: result of ‘1 << 31’ requires 33 bits to represent, but ‘int’
only has 32 bits [-Wshift-overflow=]
   x = i << 31;   // no warning expected
         ^~

Reply via email to