On Tue, Sep 29, 2026 at 11:38 AM Aldy Hernandez <[email protected]> wrote:
>
> Andrea Pinski <[email protected]> writes:
>
> > On Mon, Aug 31, 2026 at 7:42 AM Léo Hardt <[email protected]> wrote:
>
> >>
> >> fix(libcpp): Don't ICE parsing __has_include outside directive.
> >> cc: libcpp maintainers.
> >>
> >> Fixes an ICE wherein 'glue_header_name' is called outside
> >> parsing a preprocessor directive, causing an entire file to
> >> be read and presumed to be a header name. Then, on the next
> >> read (the closing '>' or ')'), the parser ICEs since the input
> >> has already come to an end.
> >>
> >> Affects __has_include and __has_embed when used outside directives.
> >> Minimal reproducible crash has two tokens (both gcc and g++):
> >>
> >>    __has_include<
> >>
> >> Given glue_header_name was written for usage inside preprocessor
> >> parsing, we could either change it or not call it in case of errors.
> >> I opted to bail out early on an error case, since there is no chance
> >> it could influence valid code parsing.
> >>
> >> See more on https://gcc.gnu.org/PR121508.
> >>
> >>    PR preprocessor/121508
> >>    PR preprocessor/123339
> >>
> >> libcpp/ChangeLog:
> >>
> >>         * macro.cc (builtin_has_include_1): Bail early if
> >>         not on a preprocessor directive.
> >
> > Ok.
> >
> >>
> >> Signed-off-by: Léo Hardt <[email protected]>
> >> ---
> >>   libcpp/macro.cc | 7 +++++--
> >>   1 file changed, 5 insertions(+), 2 deletions(-)
> >>
> >> diff --git a/libcpp/macro.cc b/libcpp/macro.cc
> >> index 736c360336d..064df1d4134 100644
> >> --- a/libcpp/macro.cc
> >> +++ b/libcpp/macro.cc
> >> @@ -392,8 +392,11 @@ builtin_has_include_1 (cpp_reader *pfile, const char
> >> *name, bool *paren,
> >>                        bool *bracket, location_t *loc)
> >>   {
> >>     if (!pfile->state.in_directive)
> >> -    cpp_error (pfile, CPP_DL_ERROR,
> >> -              "%qs used outside of preprocessing directive", name);
> >> +    {
> >> +      cpp_error (pfile, CPP_DL_ERROR,
> >> +                "%qs used outside of preprocessing directive", name);
> >> +      return NULL;
> >> +    }
>
> Unless I'm missing something...

You are not.  See
https://gcc.gnu.org/pipermail/gcc-patches/2026-September/732195.html .
Since it is only c-c++-common/gomp/has-include-1.c that has been a
spurious test failure. I have not worked on it yet.

Thanks,
Andrea

>
> This commit added an early return to builtin_has_include_1 that skips
> the set to paren:
>
>   if (!pfile->state.in_directive)
>     {
>       cpp_error (pfile, CPP_DL_ERROR,
>                  "%qs used outside of preprocessing directive", name);
>       return NULL;
>     }
>
>   pfile->state.angled_headers = true;
>   const auto sav_padding = pfile->state.directive_wants_padding;
>   pfile->state.directive_wants_padding = true;
>   const cpp_token *token = _cpp_get_token_no_padding (pfile);
>   *paren = token->type == CPP_OPEN_PAREN;
>
> But every call to builtin_has_include_1 has paren uninitialized:
>
> static int
> builtin_has_include (cpp_reader *pfile, cpp_hashnode *op, bool has_next)
> {
>   int result = 0;
>   bool paren, bracket;
>   char *fname = builtin_has_include_1 (pfile, (const char *) NODE_NAME (op),
>                                        &paren, &bracket, NULL);
>
> This is causing spurious test failures for me, seemingly from the
> uninitialized read.
>
> Aldy

Reply via email to