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

--- Comment #4 from CVS Commits <cvs-commit at gcc dot gnu.org> ---
The master branch has been updated by Nathan Sidwell <nat...@gcc.gnu.org>:

https://gcc.gnu.org/g:ad1a3914ae8d67c94b0d2428e3f9672e7db491a1

commit r10-6092-gad1a3914ae8d67c94b0d2428e3f9672e7db491a1
Author: Nathan Sidwell <nat...@acm.org>
Date:   Mon Jan 20 05:39:59 2020 -0800

    [PR 80005]  Fix __has_include

    __has_include is funky in that it is macro-like from the POV of #ifdef and
    friends, but lexes its parenthesize argument #include-like.  We were
    failing the second part of that, because we used a forwarding macro to an
    internal name, and hence always lexed the argument in macro-parameter
    context.  We componded that by not setting the right flag when lexing, so
    it didn't even know.  Mostly users got lucky.

    This reimplements the handline.
    1) Remove the forwarding, but declare object-like macros that
    expand to themselves.  This satisfies the #ifdef requirement

    2) Correctly set angled_brackets when lexing the parameter.  This tells
    the lexer (a) <...> is a header name and (b) "..." is too (not a string).

    3) Remove the in__has_include lexer state, just tell find_file that that's
    what's happenning, so it doesn't emit an error.

    We lose the (undocumented) ability to #undef __has_include.  That may well
    have been an accident of implementation.  There are no tests for it.

    We gain __has_include behaviour for all users of the preprocessors -- not
    just the C-family ones that defined a forwarding macro.

        libcpp/
        PR preprocessor/80005
        * include/cpplib.h (BT_HAS_ATTRIBUTE): Fix comment.
        * internal.h (struct lexer_state): Delete in__has_include field.
        (struct spec_nodes): Rename n__has_include{,_next}__ fields.
        (_cpp_defined_macro_p): New.
        (_cpp_find_file): Add has_include parm.
        * directives.c (lex_macro_node): Combine defined,
        __has_inline{,_next} checking.
        (do_ifdef, do_ifndef): Use _cpp_defined_macro_p.
        (_cpp_init_directives): Refactor.
        * expr.c (parse_defined): Use _cpp_defined_macro_p.
        (eval_token): Adjust parse_has_include calls.
        (parse_has_include): Add OP parameter.  Reimplement.
        * files.c (_cpp_find_file): Add HAS_INCLUDE parm.  Use it to
        inhibit error message.
        (_cpp_stack_include): Adjust _cpp_find_file call.
        (_cpp_fake_include, _cpp_compare_file_date): Likewise.
        (open_file_failed): Remove in__has_include check.
        (_cpp_has_header): Adjust _cpp_find_file call.
        * identifiers.c (_cpp_init_hashtable): Don't init
        __has_include{,_next} here ...
        * init.c (cpp_init_builtins): ... init them here.  Define as
        macros.
        (cpp_read_main_file): Adjust _cpp_find_file call.
        * pch.c (cpp_read_state): Adjust __has_include{,_next} access.
        * traditional.c (_cpp_scan_out_locgical_line): Likewise.

        gcc/c-family/
        PR preprocessor/80005
        * c-cppbuiltins.c (c_cpp_builtins): Don't define __has_include{,_next}.

        gcc/testsuite/
        PR preprocessor/80005
        * g++.dg/cpp1y/feat-cxx14.C: Adjust.
        * g++.dg/cpp1z/feat-cxx17.C: Adjust.
        * g++.dg/cpp2a/feat-cxx2a.C: Adjust.
        * g++.dg/cpp/pr80005.C: New.

Reply via email to