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.

Reply via email to