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