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 ^~