[clang] [llvm] [GCOV] Modify the path parsing of gcov instrument filter (PR #183475)

via cfe-commits cfe-commits at lists.llvm.org
Mon Mar 23 19:22:08 PDT 2026


https://github.com/LeeLee26 updated https://github.com/llvm/llvm-project/pull/183475

>From 2450691aae2d8063585b22766f9a78a0f52590a6 Mon Sep 17 00:00:00 2001
From: leelee <mengxiaoduo.1 at bytedance.com>
Date: Thu, 26 Feb 2026 16:09:31 +0800
Subject: [PATCH 1/5] [GCOV] Modify the path parsing of gcov instrument filter

---
 .../Instrumentation/GCOVProfiling.cpp         | 20 ++++++++++++-------
 1 file changed, 13 insertions(+), 7 deletions(-)

diff --git a/llvm/lib/Transforms/Instrumentation/GCOVProfiling.cpp b/llvm/lib/Transforms/Instrumentation/GCOVProfiling.cpp
index 9f47c43bb9a0b..e3e36e10030ed 100644
--- a/llvm/lib/Transforms/Instrumentation/GCOVProfiling.cpp
+++ b/llvm/lib/Transforms/Instrumentation/GCOVProfiling.cpp
@@ -229,6 +229,17 @@ static SmallString<128> getFilename(const DIScope *SP, vfs::FileSystem &VFS) {
   return Path;
 }
 
+/// Canonicalize a path by making it absolute and removing dots.
+/// Compared to sys::fs::real_path, it will not resolve symlinks.
+static StringRef canonicalizePath(StringRef P) {
+  SmallString<256> Ret = P;
+  std::error_code Err = sys::fs::make_absolute(Ret);
+  if (Err)
+    return P;
+  sys::path::remove_dots(Ret, /*removedotdot*/ true);
+  return Ret;
+}
+
 namespace {
   class GCOVRecord {
   protected:
@@ -471,13 +482,8 @@ bool GCOVProfiler::isFunctionInstrumented(const Function &F) {
 
   // Path can be
   // /usr/lib/gcc/x86_64-linux-gnu/8/../../../../include/c++/8/bits/*.h so for
-  // such a case we must get the real_path.
-  if (VFS.getRealPath(Filename, RealPath)) {
-    // real_path can fail with path like "foo.c".
-    RealFilename = Filename;
-  } else {
-    RealFilename = RealPath;
-  }
+  // such a case we must get the canonicalized path.
+  StringRef RealFilename = canonicalizePath(Filename);
 
   bool ShouldInstrument;
   if (FilterRe.empty()) {

>From b0aaa45adcd4c83cc2bd665a7883aaf2c1b4004b Mon Sep 17 00:00:00 2001
From: leelee <mengxiaoduo.1 at bytedance.com>
Date: Thu, 26 Feb 2026 17:10:39 +0800
Subject: [PATCH 2/5] [GCOV] fix bug

---
 llvm/lib/Transforms/Instrumentation/GCOVProfiling.cpp | 1 -
 1 file changed, 1 deletion(-)

diff --git a/llvm/lib/Transforms/Instrumentation/GCOVProfiling.cpp b/llvm/lib/Transforms/Instrumentation/GCOVProfiling.cpp
index e3e36e10030ed..a241e27e46372 100644
--- a/llvm/lib/Transforms/Instrumentation/GCOVProfiling.cpp
+++ b/llvm/lib/Transforms/Instrumentation/GCOVProfiling.cpp
@@ -478,7 +478,6 @@ bool GCOVProfiler::isFunctionInstrumented(const Function &F) {
   }
 
   SmallString<256> RealPath;
-  StringRef RealFilename;
 
   // Path can be
   // /usr/lib/gcc/x86_64-linux-gnu/8/../../../../include/c++/8/bits/*.h so for

>From 7f9f569263c7baec8caaa1baf33aa3d5c11a4893 Mon Sep 17 00:00:00 2001
From: leelee <mengxiaoduo.1 at bytedance.com>
Date: Mon, 23 Mar 2026 16:32:21 +0800
Subject: [PATCH 3/5] [GCOV] Add: test for coverage filter without resolving
 symlinks

---
 clang/test/CodeGen/code-coverage-filter.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/clang/test/CodeGen/code-coverage-filter.c b/clang/test/CodeGen/code-coverage-filter.c
index 9248ab5b1c8d0..5f43f58f733d5 100644
--- a/clang/test/CodeGen/code-coverage-filter.c
+++ b/clang/test/CodeGen/code-coverage-filter.c
@@ -14,6 +14,11 @@
 // RUN: FileCheck -check-prefix=NONE < %t %s
 // RUN: %clang -S -emit-llvm --coverage -fprofile-filter-files=".*\.c$" -fprofile-exclude-files=".*\.h$" %s -o %t
 // RUN: FileCheck -check-prefix=JUST-C < %t %s
+// RUN: ln -sf %s %s.symlink.c
+// RUN: %clang -S -emit-llvm --coverage %s.symlink.c -o %t
+// RUN: FileCheck -check-prefix=ALL < %t %s
+// RUN: %clang -S -emit-llvm --coverage -fprofile-filter-files=".*\.symlink.c$" %s.symlink.c -o %t
+// RUN: FileCheck -check-prefix=NO-HEADER < %t %s
 
 #include "Inputs/code-coverage-filter1.h"
 #include "Inputs/code-coverage-filter2.h"

>From 53eb544dba356db3fc379bb0c3f4819c1d2b85f2 Mon Sep 17 00:00:00 2001
From: leelee <mengxiaoduo.1 at bytedance.com>
Date: Mon, 23 Mar 2026 19:14:29 +0800
Subject: [PATCH 4/5] [GCOV] Fix: SmallString return

---
 llvm/lib/Transforms/Instrumentation/GCOVProfiling.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/llvm/lib/Transforms/Instrumentation/GCOVProfiling.cpp b/llvm/lib/Transforms/Instrumentation/GCOVProfiling.cpp
index a241e27e46372..4161a1e9aa12a 100644
--- a/llvm/lib/Transforms/Instrumentation/GCOVProfiling.cpp
+++ b/llvm/lib/Transforms/Instrumentation/GCOVProfiling.cpp
@@ -237,7 +237,7 @@ static StringRef canonicalizePath(StringRef P) {
   if (Err)
     return P;
   sys::path::remove_dots(Ret, /*removedotdot*/ true);
-  return Ret;
+  return Ret.str();
 }
 
 namespace {

>From 4713fc49b86b75dc9d44d4f0ab322ebe843486eb Mon Sep 17 00:00:00 2001
From: leelee <mengxiaoduo.1 at bytedance.com>
Date: Mon, 23 Mar 2026 19:31:02 +0800
Subject: [PATCH 5/5] [GCOV] Fix: canonicalize implement

---
 .../Transforms/Instrumentation/GCOVProfiling.cpp  | 15 ++++++++++-----
 1 file changed, 10 insertions(+), 5 deletions(-)

diff --git a/llvm/lib/Transforms/Instrumentation/GCOVProfiling.cpp b/llvm/lib/Transforms/Instrumentation/GCOVProfiling.cpp
index 4161a1e9aa12a..737e9073482c1 100644
--- a/llvm/lib/Transforms/Instrumentation/GCOVProfiling.cpp
+++ b/llvm/lib/Transforms/Instrumentation/GCOVProfiling.cpp
@@ -231,13 +231,13 @@ static SmallString<128> getFilename(const DIScope *SP, vfs::FileSystem &VFS) {
 
 /// Canonicalize a path by making it absolute and removing dots.
 /// Compared to sys::fs::real_path, it will not resolve symlinks.
-static StringRef canonicalizePath(StringRef P) {
+static ErrorOr<SmallString<256>> canonicalizePath(StringRef P) {
   SmallString<256> Ret = P;
   std::error_code Err = sys::fs::make_absolute(Ret);
   if (Err)
-    return P;
+    return Err;
   sys::path::remove_dots(Ret, /*removedotdot*/ true);
-  return Ret.str();
+  return Ret;
 }
 
 namespace {
@@ -477,12 +477,17 @@ bool GCOVProfiler::isFunctionInstrumented(const Function &F) {
     return It->second;
   }
 
-  SmallString<256> RealPath;
+  StringRef RealFilename;
 
   // Path can be
   // /usr/lib/gcc/x86_64-linux-gnu/8/../../../../include/c++/8/bits/*.h so for
   // such a case we must get the canonicalized path.
-  StringRef RealFilename = canonicalizePath(Filename);
+  ErrorOr<SmallString<256>> RealPathOrErr = canonicalizePath(Filename);
+  if (!RealPathOrErr)
+    RealFilename = Filename;
+  else {
+    RealFilename = *RealPathOrErr;
+  }
 
   bool ShouldInstrument;
   if (FilterRe.empty()) {



More information about the cfe-commits mailing list