https://gcc.gnu.org/g:be496fd2aa528b4acc2002c04b7186a1f54b95e2
commit r16-4403-gbe496fd2aa528b4acc2002c04b7186a1f54b95e2 Author: Pierre Marie de Rodat <[email protected]> Date: Tue Oct 14 00:11:37 2025 +0200 libcpp: decode original directory strings for traditional CPP In traditional CPP mode (-save-temps, -no-integrated-cpp, etc.), the compilation directory is conveyed to cc1 using a line such as: # <line> "/path/name//" This string literal can contain escape sequences, for instance, if the original source file was compiled in "/tmp/a\b", then this line will be: # <line> "/tmp/a\\b//" So reading the compilation directory must decode escape sequences. This last part is currently missing and this patch implements it. libcpp/ * init.cc (read_original_directory): Attempt to decode escape sequences with cpp_interpret_string_notranslate. Diff: --- libcpp/init.cc | 31 +++++++++++++++++++++++++++---- 1 file changed, 27 insertions(+), 4 deletions(-) diff --git a/libcpp/init.cc b/libcpp/init.cc index eb495e26effc..567d5e703814 100644 --- a/libcpp/init.cc +++ b/libcpp/init.cc @@ -893,11 +893,34 @@ read_original_directory (cpp_reader *pfile) if (pfile->cb.dir_change) { - /* Smash the string directly, it's dead at this point */ - char *smashy = (char *)text; - smashy[len - 3] = 0; + cpp_string s = { 0, 0 }; + const char *dir_slashslash; + unsigned int dir_slashslash_len; + + /* If we fail to decode escape sequences in the string literal, fall + back onto the literal itself, manually removing the opening and + closing quotes ("). */ + if (cpp_interpret_string_notranslate (pfile, &string->val.str, 1, &s, + CPP_STRING)) + { + /* At this point, the trailing NUL byte in S is included in its + length, so take it out. */ + dir_slashslash = (const char *) s.text; + dir_slashslash_len = s.len - 1; + } + else + { + dir_slashslash = (const char *) string->val.str.text + 1; + dir_slashslash_len = string->val.str.len - 2; + } + + /* Strip the trailing double slash. */ + const unsigned dir_len = dir_slashslash_len - 2; + char *dir = (char *) alloca (dir_len + 1); + memcpy (dir, dir_slashslash, dir_len); + dir[dir_len] = '\0'; - pfile->cb.dir_change (pfile, smashy + 1); + pfile->cb.dir_change (pfile, dir); } /* We should be at EOL. */
