https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69126
--- Comment #8 from David Malcolm <dmalcolm at gcc dot gnu.org> --- Looking at calls to linemap_compare_locations, the crucial comparison is the comparison of the location of the 2nd diagnostic with that of the "ignore" pragma: Breakpoint 2, linemap_compare_locations (set=0x7ffff7ffb000, pre=226930, post=post@entry=2147483645) at ../../src/libcpp/line-map.c:1311 (gdb) call inform (226930, "pre, the location of the ignore") /tmp/test.cc:17:24: note: pre, the location of the ignore MACRO; ^ (gdb) call inform (2147483645, "post, the location of the diagnostic") /tmp/test.cc:13:9: note: post, the location of the diagnostic int x; ^ /tmp/test.cc:17:5: note: in expansion of macro ‘MACRO’ MACRO; ^~~~~ The initial value of l1 == post (location of the diagnostic): (gdb) p /x l1 $15 = 0x7ffffffd linemap_compare_locations expands macro locations at LRK_MACRO_EXPANSION_POINT and obtains: (gdb) p l1 $19 = 226308 (gdb) call inform (226308, "") /tmp/test.cc:17:5: note: MACRO; ^~~~~ and hence treats the location of "post" (the diagnostic) as the "M" of the macro expansion point. However, the location of the "ignore" within the macro definition is 226930, which is *after* that "M": (gdb) call inform (226930, "pre, the location of the ignore") /tmp/test.cc:17:24: note: pre, the location of the ignore MACRO; ^ Hence that strange-looking synthesized location of the "ignore" directive within the tokens synthesized by _cpp_do__Pragma is effectively *after* that of the macro expansion point. Hence the "ignore" is treated as occurring after the diagnostic, hence the "ignore" doesn't affect the diagnostic, and the warning is emitted. FWIW, there's also some logic in linemap_compare_locations for handling locations in the same macro expansion, but this isn't the case here as the location of the pragma has been recorded as an ordinary location.