https://gcc.gnu.org/bugzilla/show_bug.cgi?id=121508

--- Comment #4 from Léo Hardt <leom.hardt at inf dot ufrgs.br> ---
After a closer inspection, I'd say the problematic behaviour comes from a
disagreement between two places:

- glue_header_name (from libcpp/directives.cc) supposes it's reading a macro.
It will read until EOF (i.e. end of the macro, end of the line) or a '>' sign. 

- builtin_has_include_1 will call that function even if it knows it's not in a
macro context,  which causes the entire file to be read, pfile->buffer to be
null, and the compiler to crash when trying to read the close parenthesis. 

Notice the test file

   int x = _has_include(<iostream this is
   junk text
   more junk text

produces:

   (1) __has_include used outside preprocessing directive (correct)
   (2) missing terminating '>' character (in line 3!, reads until EOF)
   (3) internal compiler error on reading beyond EOF, looking for ')'

To fix this bug one should decide where is a sensible place to stop trying to
parse _has_include when we already know it's inside a preprocessor directive. 

I would argue it's immediately (i.e. treat _has_include as a stray name).  This
would incur in a very very small diff, which would only affect error paths:

BEFORE:

  if (!pfile->state.in_directive)
    cpp_error (pfile, CPP_DL_ERROR,
               "%qs used outside of preprocessing directive", name);


AFTER:

  if (!pfile->state.in_directive)
   { 
    cpp_error (pfile, CPP_DL_ERROR,
               "%qs used outside of preprocessing directive", name);
    return NULL;
   } 


This NULL is already correctly handled by builtin_has_include_1's callers (such
as when you try to call __has_include with empty arguments).

Let me know what you think of this solution

Reply via email to