aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/common.opt4
-rw-r--r--gcc/coverage.c2
-rw-r--r--gcc/doc/invoke.texi14
-rw-r--r--gcc/gcov-io.c32
-rw-r--r--gcc/gcov-io.h1
-rw-r--r--gcc/profile.c2
-rw-r--r--gcc/testsuite/gcc.misc-tests/gcov-1a.c20
7 files changed, 73 insertions, 2 deletions
diff --git a/gcc/common.opt b/gcc/common.opt
index 1330555..0a10511 100644
--- a/gcc/common.opt
+++ b/gcc/common.opt
@@ -1969,6 +1969,10 @@ fprofile
Common Report Var(profile_flag)
Enable basic program profiling code.
+fprofile-abs-path
+Common Report Var(profile_abs_path_flag)
+Generate absolute source path names for gcov.
+
fprofile-arcs
Common Report Var(profile_arc_flag)
Insert arc-based program profiling code.
diff --git a/gcc/coverage.c b/gcc/coverage.c
index 53e379b..ed46910 100644
--- a/gcc/coverage.c
+++ b/gcc/coverage.c
@@ -663,7 +663,7 @@ coverage_begin_function (unsigned lineno_checksum, unsigned cfg_checksum)
gcov_write_unsigned (cfg_checksum);
gcov_write_string (IDENTIFIER_POINTER
(DECL_ASSEMBLER_NAME (current_function_decl)));
- gcov_write_string (xloc.file);
+ gcov_write_filename (xloc.file);
gcov_write_unsigned (xloc.line);
gcov_write_length (offset);
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index e691f48..4a83a3e 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -444,6 +444,7 @@ Objective-C and Objective-C++ Dialects}.
@item Program Instrumentation Options
@xref{Instrumentation Options,,Program Instrumentation Options}.
@gccoptlist{-p -pg -fprofile-arcs --coverage -ftest-coverage @gol
+-fprofile-abs-path @gol
-fprofile-dir=@var{path} -fprofile-generate -fprofile-generate=@var{path} @gol
-fsanitize=@var{style} -fsanitize-recover -fsanitize-recover=@var{style} @gol
-fasan-shadow-offset=@var{number} -fsanitize-sections=@var{s1},@var{s2},... @gol
@@ -10695,6 +10696,12 @@ additional @option{-ftest-coverage} option. You do not need to profile
every source file in a program.
@item
+Compile the source files additionally with @option{-fprofile-abs-path}
+to create absolute path names in the @file{.gcno} files. This allows
+@command{gcov} to find the correct sources in projects where compilations
+occur with different working directories.
+
+@item
Link your object files with @option{-lgcov} or @option{-fprofile-arcs}
(the latter implies the former).
@@ -10738,6 +10745,13 @@ above for a description of @var{auxname} and instructions on how to
generate test coverage data. Coverage data matches the source files
more closely if you do not optimize.
+@item -fprofile-abs-path
+@opindex fprofile-abs-path
+Automatically convert relative source file names to absolute path names
+in the @file{.gcno} files. This allows @command{gcov} to find the correct
+sources in projects where compilations occur with different working
+directories.
+
@item -fprofile-dir=@var{path}
@opindex fprofile-dir
diff --git a/gcc/gcov-io.c b/gcc/gcov-io.c
index 64dedd5..2ce26f4 100644
--- a/gcc/gcov-io.c
+++ b/gcc/gcov-io.c
@@ -357,6 +357,38 @@ gcov_write_string (const char *string)
#endif
#if !IN_LIBGCOV
+/* Write FILENAME to coverage file. Sets error flag on file
+ error, overflow flag on overflow */
+
+GCOV_LINKAGE void
+gcov_write_filename (const char *filename)
+{
+ if (profile_abs_path_flag && filename && filename[0]
+ && !(IS_DIR_SEPARATOR (filename[0])
+#if HAVE_DOS_BASED_FILE_SYSTEM
+ || filename[1] == ':'
+#endif
+ ))
+ {
+ char *buf = getcwd (NULL, 0);
+ if (buf != NULL && buf[0])
+ {
+ size_t len = strlen (buf);
+ buf = (char*)xrealloc (buf, len + strlen (filename) + 2);
+ if (!IS_DIR_SEPARATOR (buf[len - 1]))
+ strcat (buf, "/");
+ strcat (buf, filename);
+ gcov_write_string (buf);
+ free (buf);
+ return;
+ }
+ }
+
+ gcov_write_string (filename);
+}
+#endif
+
+#if !IN_LIBGCOV
/* Write a tag TAG and reserve space for the record length. Return a
value to be used for gcov_write_length. */
diff --git a/gcc/gcov-io.h b/gcc/gcov-io.h
index 1c8ee8f..584c3a2 100644
--- a/gcc/gcov-io.h
+++ b/gcc/gcov-io.h
@@ -387,6 +387,7 @@ GCOV_LINKAGE void gcov_write_unsigned (gcov_unsigned_t) ATTRIBUTE_HIDDEN;
/* Available only in compiler */
GCOV_LINKAGE unsigned gcov_histo_index (gcov_type value);
GCOV_LINKAGE void gcov_write_string (const char *);
+GCOV_LINKAGE void gcov_write_filename (const char *);
GCOV_LINKAGE gcov_position_t gcov_write_tag (gcov_unsigned_t);
GCOV_LINKAGE void gcov_write_length (gcov_position_t /*position*/);
#endif
diff --git a/gcc/profile.c b/gcc/profile.c
index aca5c67..219fa8a 100644
--- a/gcc/profile.c
+++ b/gcc/profile.c
@@ -976,7 +976,7 @@ output_location (char const *file_name, int line,
{
prev_file_name = file_name;
gcov_write_unsigned (0);
- gcov_write_string (prev_file_name);
+ gcov_write_filename (prev_file_name);
}
if (line_differs)
{
diff --git a/gcc/testsuite/gcc.misc-tests/gcov-1a.c b/gcc/testsuite/gcc.misc-tests/gcov-1a.c
new file mode 100644
index 0000000..2b9fabc
--- /dev/null
+++ b/gcc/testsuite/gcc.misc-tests/gcov-1a.c
@@ -0,0 +1,20 @@
+/* Test Gcov basics. */
+
+/* { dg-options "-fprofile-arcs -ftest-coverage -fprofile-abs-path" } */
+/* { dg-do run { target native } } */
+
+void noop ()
+{
+}
+
+int main ()
+{
+ int i;
+
+ for (i = 0; i < 10; i++) /* count(11) */
+ noop (); /* count(10) */
+
+ return 0; /* count(1) */
+}
+
+/* { dg-final { run-gcov gcov-1a.c } } */