]> git.ipfire.org Git - thirdparty/ccache.git/commitdiff
fix: Rewrite 'inlined from' messages in absolute_paths_in_stderr (#1676) master
authorEnrico Seiler <eseiler@users.noreply.github.com>
Tue, 27 Jan 2026 18:39:41 +0000 (19:39 +0100)
committerGitHub <noreply@github.com>
Tue, 27 Jan 2026 18:39:41 +0000 (19:39 +0100)
src/ccache/core/common.cpp
unittest/test_core_common.cpp

index 0a6ac2b8488904c7c1e66ed296bc561030f15af8..9106b27f7fa481b9ba183532421260b44562cd13 100644 (file)
@@ -90,8 +90,32 @@ make_relative_path(const Context& ctx, const fs::path& path)
   }
 }
 
-std::string
-rewrite_stderr_to_absolute_paths(std::string_view text)
+inline bool
+parse_inlined_from_msg(std::string_view& line, std::string& result)
+{
+  // Reference for GCC: <https://github.com/gcc-mirror/gcc/blob/
+  // c7507e395f096240ffa8fa5dfcbfcfd8c5e23bb8/gcc/langhooks.cc#L450-L467>
+  static const std::string_view inlined_from_msg = "    inlined from ";
+  static const std::string_view inlined_from_msg_separator = " at ";
+
+  if (!util::starts_with(line, inlined_from_msg)) {
+    return false;
+  }
+
+  size_t signature_end = line.find(inlined_from_msg_separator);
+  if (signature_end == std::string_view::npos) {
+    return false;
+  }
+
+  signature_end += inlined_from_msg_separator.size();
+  result.append(line.data(), signature_end);
+  line = line.substr(signature_end);
+
+  return true;
+}
+
+inline bool
+parse_in_file_included_from_msg(std::string_view& line, std::string& result)
 {
   // Line prefixes from GCC plus extra space at the end. Reference:
   // <https://gcc.gnu.org/git?p=gcc.git;a=blob;f=gcc/diagnostic-format-text.cc;
@@ -106,18 +130,28 @@ rewrite_stderr_to_absolute_paths(std::string_view text)
     "imported at ",
   };
 
+  for (const auto& in_file_included_from : in_file_included_from_msgs) {
+    if (util::starts_with(line, in_file_included_from)) {
+      result += in_file_included_from;
+      line = line.substr(in_file_included_from.length());
+      return true;
+    }
+  }
+
+  return false;
+}
+
+std::string
+rewrite_stderr_to_absolute_paths(std::string_view text)
+{
   std::string result;
   using util::Tokenizer;
   for (auto line : Tokenizer(text,
                              "\n",
                              Tokenizer::Mode::include_empty,
                              Tokenizer::IncludeDelimiter::yes)) {
-    for (const auto& in_file_included_from : in_file_included_from_msgs) {
-      if (util::starts_with(line, in_file_included_from)) {
-        result += in_file_included_from;
-        line = line.substr(in_file_included_from.length());
-        break;
-      }
+    if (!parse_inlined_from_msg(line, result)) {
+      parse_in_file_included_from_msg(line, result);
     }
     while (!line.empty() && line[0] == 0x1b) {
       auto csi_seq = find_first_ansi_csi_seq(line);
index 9241cf4b02b7a6c075dc5900b54022f00e737aff..96441b2009b8c879741db860796995c8602b56f6 100644 (file)
@@ -80,7 +80,9 @@ TEST_CASE("core::rewrite_stderr_to_absolute_paths")
     "In module imported at \x1b[01m\x1b[Kexisting:\x1b[m\x1b[K: foo\n"
     "In module imported at \x1b[01m\x1b[Kexisting:47:11:\x1b[m\x1b[K: foo\n"
     "imported at \x1b[01m\x1b[Kexisting:\x1b[m\x1b[K: foo\n"
-    "imported at \x1b[01m\x1b[Kexisting:47:11:\x1b[m\x1b[K: foo\n";
+    "imported at \x1b[01m\x1b[Kexisting:47:11:\x1b[m\x1b[K: foo\n"
+    "    inlined from foo at \x1b[01m\x1b[Kexisting:\x1b[m\x1b[K\n"
+    "    inlined from foo at \x1b[01m\x1b[Kexisting:47:11,\x1b[m\x1b[K\n";
   std::string expected = FMT(
     "a:1:2\n"
     "a(3):\n"
@@ -109,7 +111,9 @@ TEST_CASE("core::rewrite_stderr_to_absolute_paths")
     "In module imported at \x1b[01m\x1b[K{0}:\x1b[m\x1b[K: foo\n"
     "In module imported at \x1b[01m\x1b[K{0}:47:11:\x1b[m\x1b[K: foo\n"
     "imported at \x1b[01m\x1b[K{0}:\x1b[m\x1b[K: foo\n"
-    "imported at \x1b[01m\x1b[K{0}:47:11:\x1b[m\x1b[K: foo\n",
+    "imported at \x1b[01m\x1b[K{0}:47:11:\x1b[m\x1b[K: foo\n"
+    "    inlined from foo at \x1b[01m\x1b[K{0}:\x1b[m\x1b[K\n"
+    "    inlined from foo at \x1b[01m\x1b[K{0}:47:11,\x1b[m\x1b[K\n",
     *fs::canonical("existing"));
   CHECK(core::rewrite_stderr_to_absolute_paths(input) == expected);
 }