http://gcc.gnu.org/bugzilla/show_bug.cgi?id=39213
--- Comment #16 from Eric Botcazou <ebotcazou at gcc dot gnu.org> 2010-12-18 17:35:48 UTC --- > I wonder if this wouldn't fix it (at least, that's similar to how lex.c guards > calling of _cpp_process_line_notes). I can't reproduce it myself, so have to > guess... The problem is that #pragma redefine_extname breaks the balance of calls to _cpp_overlay_buffer and _cpp_remove_overlay: Breakpoint 1, _cpp_overlay_buffer (pfile=0x104705160, start=0x104714050 " redefine_extname\tmkstemp64\tmkstemp\nE64_SOURCE)\nLONG)\n& (3 - 0 >= 4))\nNned(_XOPEN_SOURCE)) || \t\tdefined(_KERNEL) || defined(_KMEMUSER) || \t\tdefined(__EXTENSIONS__)\n", len=35) at /nile.build/botcazou/gcc-head/src/libcpp/traditional.c:269 269 cpp_buffer *buffer = pfile->buffer; (gdb) p pfile->overlaid_buffer $3 = (cpp_buffer *) 0x0 (gdb) continue Continuing. Breakpoint 1, _cpp_overlay_buffer (pfile=0x104705160, start=0x104714050 "\t \nseemp64\tmkstemp\nkstemp64\tmkstemp\nE64_SOURCE)\nLONG)\n& (3 - 0 >= 4))\nNned(_XOPEN_SOURCE)) || \t\tdefined(_KERNEL) || defined(_KMEMUSER) || \t\tdefined(__EXTENSIONS__)\n", len=2) at /nile.build/botcazou/gcc-head/src/libcpp/traditional.c:269 269 cpp_buffer *buffer = pfile->buffer; (gdb) p pfile->overlaid_buffer $4 = (cpp_buffer *) 0x10470ad98 because in_deferred_pragma is true in: /* Called when leaving a directive, _Pragma or command-line directive. */ static void end_directive (cpp_reader *pfile, int skip_line) { if (pfile->state.in_deferred_pragma) ; else if (CPP_OPTION (pfile, traditional)) { /* Revert change of prepare_directive_trad. */ pfile->state.prevent_expansion--; if (pfile->directive != &dtable[T_DEFINE]) _cpp_remove_overlay (pfile); } It is only reset to false in _cpp_lex_direct but this is apparently too late to call _cpp_remove_overlay from there: Index: lex.c =================================================================== --- lex.c (revision 167901) +++ lex.c (working copy) @@ -1944,6 +1944,8 @@ _cpp_lex_direct (cpp_reader *pfile) pfile->state.in_deferred_pragma = false; if (!pfile->state.pragma_allow_expansion) pfile->state.prevent_expansion--; + if (CPP_OPTION (pfile, traditional)) + _cpp_remove_overlay (pfile); return result; } if (!_cpp_get_fresh_line (pfile)) yields a SIGSEGV in _cpp_remove_overlay. The obvious change to end_directive seems to work though, revised patch to be attached.