diff options
author | Lewis Hyatt <lhyatt@gmail.com> | 2023-09-15 13:31:51 -0400 |
---|---|---|
committer | Lewis Hyatt <lhyatt@gmail.com> | 2023-09-20 16:44:24 -0400 |
commit | 601dbf2a799f691688dfe78250b5bea2717b5b5e (patch) | |
tree | b5309aa08914667b85299fe105b7c5881910a495 /libcpp | |
parent | b512d705797a65dbfe3a9ad100218192c7528b02 (diff) | |
download | gcc-601dbf2a799f691688dfe78250b5bea2717b5b5e.zip gcc-601dbf2a799f691688dfe78250b5bea2717b5b5e.tar.gz gcc-601dbf2a799f691688dfe78250b5bea2717b5b5e.tar.bz2 |
libcpp: Fix ICE on #include after a line marker directive [PR61474]
As noted in the PR, GCC will segfault if a file name is first seen in a
linemarker directive, and then later seen in a normal #include. This is
because the fake include process adds the file to the cache with a null PATH
member. The normal #include finds this file in the cache and then attempts
to use the null PATH. Resolve by adding the file to the cache with a unique
starting directory, so that the fake entry will only be found by a
subsequent fake include, not by a real one.
libcpp/ChangeLog:
PR preprocessor/61474
* files.cc (_cpp_find_file): Set DONT_READ to TRUE for fake
include files.
(_cpp_fake_include): Pass a unique cpp_dir* address so
the fake file will not be found when looked up for real.
gcc/testsuite/ChangeLog:
PR preprocessor/61474
* c-c++-common/cpp/pr61474-2.h: New test.
* c-c++-common/cpp/pr61474.c: New test.
* c-c++-common/cpp/pr61474.h: New test.
Diffstat (limited to 'libcpp')
-rw-r--r-- | libcpp/files.cc | 11 |
1 files changed, 9 insertions, 2 deletions
diff --git a/libcpp/files.cc b/libcpp/files.cc index 43a8894..27301d7 100644 --- a/libcpp/files.cc +++ b/libcpp/files.cc @@ -541,7 +541,9 @@ _cpp_find_file (cpp_reader *pfile, const char *fname, cpp_dir *start_dir, = (kind == _cpp_FFK_PRE_INCLUDE || (pfile->buffer && pfile->buffer->file->implicit_preinclude)); - if (kind != _cpp_FFK_FAKE) + if (kind == _cpp_FFK_FAKE) + file->dont_read = true; + else /* Try each path in the include chain. */ for (;;) { @@ -1490,7 +1492,12 @@ cpp_clear_file_cache (cpp_reader *pfile) void _cpp_fake_include (cpp_reader *pfile, const char *fname) { - _cpp_find_file (pfile, fname, pfile->buffer->file->dir, 0, _cpp_FFK_FAKE, 0); + /* It does not matter what are the contents of fake_source_dir, it will never + be inspected; we just use its address to uniquely signify that this file + was added as a fake include, so a later call to _cpp_find_file (to include + the file for real) won't find the fake one in the hash table. */ + static cpp_dir fake_source_dir; + _cpp_find_file (pfile, fname, &fake_source_dir, 0, _cpp_FFK_FAKE, 0); } /* Not everyone who wants to set system-header-ness on a buffer can |