https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113028
Bug ID: 113028 Summary: GCC diagnostic pop changes errors to warnings Product: gcc Version: 10.1.0 Status: UNCONFIRMED Keywords: diagnostic Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: dustbingtb at verizon dot net Target Milestone: --- Target: x86_64-linux-gnu While debugging compile errors in open-source code after upgrading gcc from 9.x, I ran into this problem with GCC diagnostic push/ignored/pop. It seems similar to old/resolved Bug 66098/Bug 66711, except it doesn't involve any -Werror command-line option; in fact, it can be reproduced with just "g++ testfile.cpp". This diagnostic error was added in gcc 10.x, so the specific example isn't meaningful prior to that; however, the problem persists through gcc 13.2 and trunk, as per godbolt. The following code easily demonstrates all the investigative cases just by modifying the value of TEST_CASE: - TEST_CASE 0 shows two "error: narrowing conversion of '-2023406815' from 'int' to 'unsigned int' [-Wnarrowing]", which is apparently a correct error diagnostic that should have been reported by earlier gcc but wasn't (at least, earlier clang has reported this diagnostic error since at least 2012, and handles the push/pop properly since then also, BTW). - TEST_CASE 1 just demonstrates that, when the first error's code is removed from compilation, the second error still fires as expected (contrast with behavior of TEST_CASE 3). - TEST_CASE 2 uses GCC diagnostic ignored "-Wnarrowing" to disable both errors, which works. - TEST_CASE 3: the bug. GCC diagnostic push/ignored suppress the first error, but pop does NOT restore the second error; instead, the second error mysteriously becomes a warning instead! // 0: two errors; 1: one (2nd) error; 2: both ignored; 3: 1st ignored 2nd warns! #define TEST_CASE 3 int main(int argc, char *argv[]) { const int HEX_CONST = (int)0x87654321L; #if TEST_CASE == 3 _Pragma("GCC diagnostic push") #endif #if TEST_CASE >= 2 _Pragma("GCC diagnostic ignored \"-Wnarrowing\"") #endif unsigned uval = (unsigned)argc; #if TEST_CASE != 1 switch (uval) { case HEX_CONST: ++uval; default: break; } #endif // TEST_CASE != 1 #if TEST_CASE == 3 _Pragma("GCC diagnostic pop") #endif switch (--uval) { case HEX_CONST: return 0; default: return 1; } }