https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105608
--- Comment #20 from GCC Commits <cvs-commit at gcc dot gnu.org> --- The master branch has been updated by Lewis Hyatt <[email protected]>: https://gcc.gnu.org/g:d538348556bd05fba13e41cb8497bda2eb086e63 commit r16-5110-gd538348556bd05fba13e41cb8497bda2eb086e63 Author: Lewis Hyatt <[email protected]> Date: Wed Jul 30 19:20:55 2025 -0400 libcpp: Improve locations for macros defined prior to PCH include [PR105608] It is permissible to define macros prior to including a PCH, as long as these definitions are disjoint from or identical to the macros in the PCH. The PCH loading process replaces all libcpp data structures with those from the PCH, so it is necessary to remember the extra macros separately and then restore them after loading the PCH, which all is handled by cpp_save_state() and cpp_read_state() in libcpp/pch.cc. The restoration process consists of pushing a buffer containing the macro definition and then lexing it from there, similar to how a command-line -D option is processed. The current implementation does not attempt to set up the line_map for this process, and so the locations assigned to the macros are often not meaningful. (Similar to what happened in the past with lexing the tokens out of a _Pragma string, lexing out of a buffer rather than a file produces "sorta" reasonable locations that are often close enough, but not reliably correct.) Fix that up by remembering enough additional information (more or less, an expanded_location for each macro definition) to produce a reasonable location for the newly restored macros. One issue that came up is the treatment of command-line-defined macros. From the perspective of the generic line_map data structures, the command-line location is not distinguishable from other locations; it's just an ordinary location created by the front ends with a fake file name by convention. (At the moment, it is always the string `<command-line>', subject to translation.) Since libcpp needs to assign macros to that location, it needs to know what location to use, so I added a new member line_maps::cmdline_location for the front ends to set, similar to how line_maps::builtin_location is handled. This revealed a small issue, in c-opts.cc we have: /* All command line defines must have the same location. */ cpp_force_token_locations (parse_in, line_table->highest_line); But contrary to the comment, all command line defines don't actually end up with the same location anymore. This is because libcpp/lex.cc has been expanded (r6-4873) to include range information on the returned locations. That logic has never been respecting the request of cpp_force_token_locations. I believe this was not intentional, and so I have corrected that here. Prior to this patch, the range logic has been leading to command-line macros all having similar locations in the same line map (or ad-hoc locations based from there for sufficiently long tokens); with this change, they all have exactly the same location and that location is recorded in line_maps::cmdline_location. With that change, then it works fine for pch.cc to restore macros whether they came from the command-line or from the main file. gcc/c-family/ChangeLog: PR preprocessor/105608 * c-opts.cc (c_finish_options): Set new member line_table->cmdline_location. * c-pch.cc (c_common_read_pch): Adapt linemap usage to changes in libcpp pch.cc; it is now possible that the linemap is in a different file after returning from cpp_read_state(). libcpp/ChangeLog: PR preprocessor/105608 * include/line-map.h: Add new member CMDLINE_LOCATION. * lex.cc (get_location_for_byte_range_in_cur_line): Do not expand the token location to include range information if token location override was requested. (warn_about_normalization): Likewise. (_cpp_lex_direct): Likewise. * pch.cc (struct saved_macro): New local struct. (struct save_macro_data): Change DEFNS vector to hold saved_macro rather than uchar*. (save_macros): Adapt to remember the location information for each saved macro in addition to the definition. (cpp_prepare_state): Likewise. (cpp_read_state): Use the saved location information to generate proper locations for the restored macros. gcc/testsuite/ChangeLog: PR preprocessor/105608 * g++.dg/pch/line-map-3.C: Remove xfails. * g++.dg/pch/line-map-4.C: New test. * g++.dg/pch/line-map-4.Hs: New test.
