[clang] [llvm] [Clang] Add `-fsanitize-prefix-map` for remapping source paths in sanitizer metadata (PR #186908)
https://github.com/bjosv updated https://github.com/llvm/llvm-project/pull/186908 From 99edbcc918d9032b163bfac8afa5392f3abf1600 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Svensson?= Date: Mon, 16 Mar 2026 20:07:40 +0100 Subject: [PATCH] [Clang] Add -fsanitize-prefix-map= to remap source paths in sanitizer metadata MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add a new option -fsanitize-prefix-map=OLD=NEW that remaps file paths embedded in sanitizer metadata (ASan global module names and UBSan source locations). This enables reproducible builds when source trees reside at different absolute paths. The flag is also implied by -ffile-prefix-map=, consistent with how -fcoverage-prefix-map and -fmacro-prefix-map already work. Signed-off-by: Björn Svensson --- clang/docs/AddressSanitizer.rst | 22 clang/docs/ReleaseNotes.rst | 4 +++ clang/docs/UndefinedBehaviorSanitizer.rst | 5 +++ clang/docs/UsersManual.rst| 2 ++ clang/include/clang/Basic/CodeGenOptions.h| 3 ++ clang/include/clang/Options/Options.td| 5 +++ clang/lib/CodeGen/BackendUtil.cpp | 2 ++ clang/lib/CodeGen/CGExpr.cpp | 9 + clang/lib/Driver/ToolChains/Clang.cpp | 16 + clang/lib/Frontend/CompilerInvocation.cpp | 9 + clang/test/CodeGen/asan-prefix-map.cpp| 12 +++ clang/test/CodeGen/ubsan-prefix-map.cpp | 10 ++ clang/test/Driver/fsanitize-prefix-map.cpp| 8 + .../Instrumentation/AddressSanitizer.h| 1 + .../Instrumentation/AddressSanitizer.cpp | 34 ++- 15 files changed, 134 insertions(+), 8 deletions(-) create mode 100644 clang/test/CodeGen/asan-prefix-map.cpp create mode 100644 clang/test/CodeGen/ubsan-prefix-map.cpp create mode 100644 clang/test/Driver/fsanitize-prefix-map.cpp diff --git a/clang/docs/AddressSanitizer.rst b/clang/docs/AddressSanitizer.rst index 80b1cdd95d77a..a007e86115caa 100644 --- a/clang/docs/AddressSanitizer.rst +++ b/clang/docs/AddressSanitizer.rst @@ -408,6 +408,28 @@ run-time performance, which leads to increased binary size. Using the flag forces all code instrumentation to be outlined, which reduces the size of the generated code, but also reduces the run-time performance. +Remapping source paths +-- + +AddressSanitizer embeds the source file path in global metadata. For +reproducible builds, the option ``-fsanitize-prefix-map=OLD=NEW`` can be used +to remap these paths. If a source path starts with ``OLD``, it will be replaced +with ``NEW``. + +Example +^^^ + +.. code-block:: console + + # Strip build directory prefix + $ clang -fsanitize=address -fsanitize-prefix-map=/build/dir/= source.c + + # Remap to a canonical path + $ clang -fsanitize=address -fsanitize-prefix-map=/home/user/project=/src source.c + +Multiple ``-fsanitize-prefix-map`` options can be specified; the first matching +prefix wins. + Limitations === diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 9e4a47a5b18fc..0eae7ce0d606f 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -929,6 +929,10 @@ Sanitizers -- - UndefinedBehaviorSanitizer now supports ``__ubsan_default_suppressions``. +- Added ``-fsanitize-prefix-map=OLD=NEW`` option to remap source file paths + in sanitizer metadata, enabling reproducible builds. This flag is also + implied by ``-ffile-prefix-map``. + Python Binding Changes -- - Add deprecation warnings to ``CompletionChunk.isKind...`` methods. diff --git a/clang/docs/UndefinedBehaviorSanitizer.rst b/clang/docs/UndefinedBehaviorSanitizer.rst index 3ff1a77e33a6c..683044f621e74 100644 --- a/clang/docs/UndefinedBehaviorSanitizer.rst +++ b/clang/docs/UndefinedBehaviorSanitizer.rst @@ -522,6 +522,10 @@ information. If ``N`` is positive, file information emitted by UndefinedBehaviorSanitizer will drop the first ``N`` components from the file path. If ``N`` is negative, the last ``N`` components will be kept. +Alternatively, ``-fsanitize-prefix-map=OLD=NEW`` can be used to remap file +paths. If a source path starts with ``OLD``, it will be replaced with ``NEW``. +Both options can be combined; the prefix map is applied first. + Example --- @@ -532,6 +536,7 @@ For a file called ``/code/library/file.cpp``, here is what would be emitted: * ``-fsanitize-undefined-strip-path-components=2``: ``library/file.cpp`` * ``-fsanitize-undefined-strip-path-components=-1``: ``file.cpp`` * ``-fsanitize-undefined-strip-path-components=-2``: ``library/file.cpp`` +* ``-fsanitize-prefix-map=/code/=``: ``library/file.cpp`` More Information diff --git a/clang/docs/UsersManual.rst b/clang/docs/UsersManual.rst index 3392a210f0bb0..992a5c9337294 100644 --- a/clang/docs/UsersManual.rst +++ b/clang/docs/UsersManual.rst @@
[clang] [llvm] [Clang] Add `-fsanitize-prefix-map` for remapping source paths in sanitizer metadata (PR #186908)
bjosv wrote: Rebased this PR even that we also have the ongoing https://github.com/llvm/llvm-project/pull/201803 https://github.com/llvm/llvm-project/pull/186908 ___ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [Clang] Add `-fsanitize-prefix-map` for remapping source paths in sanitizer metadata (PR #186908)
https://github.com/bjosv updated https://github.com/llvm/llvm-project/pull/186908 From 99edbcc918d9032b163bfac8afa5392f3abf1600 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Svensson?= Date: Mon, 16 Mar 2026 20:07:40 +0100 Subject: [PATCH] [Clang] Add -fsanitize-prefix-map= to remap source paths in sanitizer metadata MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add a new option -fsanitize-prefix-map=OLD=NEW that remaps file paths embedded in sanitizer metadata (ASan global module names and UBSan source locations). This enables reproducible builds when source trees reside at different absolute paths. The flag is also implied by -ffile-prefix-map=, consistent with how -fcoverage-prefix-map and -fmacro-prefix-map already work. Signed-off-by: Björn Svensson --- clang/docs/AddressSanitizer.rst | 22 clang/docs/ReleaseNotes.rst | 4 +++ clang/docs/UndefinedBehaviorSanitizer.rst | 5 +++ clang/docs/UsersManual.rst| 2 ++ clang/include/clang/Basic/CodeGenOptions.h| 3 ++ clang/include/clang/Options/Options.td| 5 +++ clang/lib/CodeGen/BackendUtil.cpp | 2 ++ clang/lib/CodeGen/CGExpr.cpp | 9 + clang/lib/Driver/ToolChains/Clang.cpp | 16 + clang/lib/Frontend/CompilerInvocation.cpp | 9 + clang/test/CodeGen/asan-prefix-map.cpp| 12 +++ clang/test/CodeGen/ubsan-prefix-map.cpp | 10 ++ clang/test/Driver/fsanitize-prefix-map.cpp| 8 + .../Instrumentation/AddressSanitizer.h| 1 + .../Instrumentation/AddressSanitizer.cpp | 34 ++- 15 files changed, 134 insertions(+), 8 deletions(-) create mode 100644 clang/test/CodeGen/asan-prefix-map.cpp create mode 100644 clang/test/CodeGen/ubsan-prefix-map.cpp create mode 100644 clang/test/Driver/fsanitize-prefix-map.cpp diff --git a/clang/docs/AddressSanitizer.rst b/clang/docs/AddressSanitizer.rst index 80b1cdd95d77a..a007e86115caa 100644 --- a/clang/docs/AddressSanitizer.rst +++ b/clang/docs/AddressSanitizer.rst @@ -408,6 +408,28 @@ run-time performance, which leads to increased binary size. Using the flag forces all code instrumentation to be outlined, which reduces the size of the generated code, but also reduces the run-time performance. +Remapping source paths +-- + +AddressSanitizer embeds the source file path in global metadata. For +reproducible builds, the option ``-fsanitize-prefix-map=OLD=NEW`` can be used +to remap these paths. If a source path starts with ``OLD``, it will be replaced +with ``NEW``. + +Example +^^^ + +.. code-block:: console + + # Strip build directory prefix + $ clang -fsanitize=address -fsanitize-prefix-map=/build/dir/= source.c + + # Remap to a canonical path + $ clang -fsanitize=address -fsanitize-prefix-map=/home/user/project=/src source.c + +Multiple ``-fsanitize-prefix-map`` options can be specified; the first matching +prefix wins. + Limitations === diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 9e4a47a5b18fc..0eae7ce0d606f 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -929,6 +929,10 @@ Sanitizers -- - UndefinedBehaviorSanitizer now supports ``__ubsan_default_suppressions``. +- Added ``-fsanitize-prefix-map=OLD=NEW`` option to remap source file paths + in sanitizer metadata, enabling reproducible builds. This flag is also + implied by ``-ffile-prefix-map``. + Python Binding Changes -- - Add deprecation warnings to ``CompletionChunk.isKind...`` methods. diff --git a/clang/docs/UndefinedBehaviorSanitizer.rst b/clang/docs/UndefinedBehaviorSanitizer.rst index 3ff1a77e33a6c..683044f621e74 100644 --- a/clang/docs/UndefinedBehaviorSanitizer.rst +++ b/clang/docs/UndefinedBehaviorSanitizer.rst @@ -522,6 +522,10 @@ information. If ``N`` is positive, file information emitted by UndefinedBehaviorSanitizer will drop the first ``N`` components from the file path. If ``N`` is negative, the last ``N`` components will be kept. +Alternatively, ``-fsanitize-prefix-map=OLD=NEW`` can be used to remap file +paths. If a source path starts with ``OLD``, it will be replaced with ``NEW``. +Both options can be combined; the prefix map is applied first. + Example --- @@ -532,6 +536,7 @@ For a file called ``/code/library/file.cpp``, here is what would be emitted: * ``-fsanitize-undefined-strip-path-components=2``: ``library/file.cpp`` * ``-fsanitize-undefined-strip-path-components=-1``: ``file.cpp`` * ``-fsanitize-undefined-strip-path-components=-2``: ``library/file.cpp`` +* ``-fsanitize-prefix-map=/code/=``: ``library/file.cpp`` More Information diff --git a/clang/docs/UsersManual.rst b/clang/docs/UsersManual.rst index 3392a210f0bb0..992a5c9337294 100644 --- a/clang/docs/UsersManual.rst +++ b/clang/docs/UsersManual.rst @@
[clang] [llvm] [Clang] Add `-fsanitize-prefix-map` for remapping source paths in sanitizer metadata (PR #186908)
https://github.com/bjosv updated https://github.com/llvm/llvm-project/pull/186908 From 99edbcc918d9032b163bfac8afa5392f3abf1600 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Svensson?= Date: Mon, 16 Mar 2026 20:07:40 +0100 Subject: [PATCH] [Clang] Add -fsanitize-prefix-map= to remap source paths in sanitizer metadata MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add a new option -fsanitize-prefix-map=OLD=NEW that remaps file paths embedded in sanitizer metadata (ASan global module names and UBSan source locations). This enables reproducible builds when source trees reside at different absolute paths. The flag is also implied by -ffile-prefix-map=, consistent with how -fcoverage-prefix-map and -fmacro-prefix-map already work. Signed-off-by: Björn Svensson --- clang/docs/AddressSanitizer.rst | 22 clang/docs/ReleaseNotes.rst | 4 +++ clang/docs/UndefinedBehaviorSanitizer.rst | 5 +++ clang/docs/UsersManual.rst| 2 ++ clang/include/clang/Basic/CodeGenOptions.h| 3 ++ clang/include/clang/Options/Options.td| 5 +++ clang/lib/CodeGen/BackendUtil.cpp | 2 ++ clang/lib/CodeGen/CGExpr.cpp | 9 + clang/lib/Driver/ToolChains/Clang.cpp | 16 + clang/lib/Frontend/CompilerInvocation.cpp | 9 + clang/test/CodeGen/asan-prefix-map.cpp| 12 +++ clang/test/CodeGen/ubsan-prefix-map.cpp | 10 ++ clang/test/Driver/fsanitize-prefix-map.cpp| 8 + .../Instrumentation/AddressSanitizer.h| 1 + .../Instrumentation/AddressSanitizer.cpp | 34 ++- 15 files changed, 134 insertions(+), 8 deletions(-) create mode 100644 clang/test/CodeGen/asan-prefix-map.cpp create mode 100644 clang/test/CodeGen/ubsan-prefix-map.cpp create mode 100644 clang/test/Driver/fsanitize-prefix-map.cpp diff --git a/clang/docs/AddressSanitizer.rst b/clang/docs/AddressSanitizer.rst index 80b1cdd95d77a..a007e86115caa 100644 --- a/clang/docs/AddressSanitizer.rst +++ b/clang/docs/AddressSanitizer.rst @@ -408,6 +408,28 @@ run-time performance, which leads to increased binary size. Using the flag forces all code instrumentation to be outlined, which reduces the size of the generated code, but also reduces the run-time performance. +Remapping source paths +-- + +AddressSanitizer embeds the source file path in global metadata. For +reproducible builds, the option ``-fsanitize-prefix-map=OLD=NEW`` can be used +to remap these paths. If a source path starts with ``OLD``, it will be replaced +with ``NEW``. + +Example +^^^ + +.. code-block:: console + + # Strip build directory prefix + $ clang -fsanitize=address -fsanitize-prefix-map=/build/dir/= source.c + + # Remap to a canonical path + $ clang -fsanitize=address -fsanitize-prefix-map=/home/user/project=/src source.c + +Multiple ``-fsanitize-prefix-map`` options can be specified; the first matching +prefix wins. + Limitations === diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 9e4a47a5b18fc..0eae7ce0d606f 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -929,6 +929,10 @@ Sanitizers -- - UndefinedBehaviorSanitizer now supports ``__ubsan_default_suppressions``. +- Added ``-fsanitize-prefix-map=OLD=NEW`` option to remap source file paths + in sanitizer metadata, enabling reproducible builds. This flag is also + implied by ``-ffile-prefix-map``. + Python Binding Changes -- - Add deprecation warnings to ``CompletionChunk.isKind...`` methods. diff --git a/clang/docs/UndefinedBehaviorSanitizer.rst b/clang/docs/UndefinedBehaviorSanitizer.rst index 3ff1a77e33a6c..683044f621e74 100644 --- a/clang/docs/UndefinedBehaviorSanitizer.rst +++ b/clang/docs/UndefinedBehaviorSanitizer.rst @@ -522,6 +522,10 @@ information. If ``N`` is positive, file information emitted by UndefinedBehaviorSanitizer will drop the first ``N`` components from the file path. If ``N`` is negative, the last ``N`` components will be kept. +Alternatively, ``-fsanitize-prefix-map=OLD=NEW`` can be used to remap file +paths. If a source path starts with ``OLD``, it will be replaced with ``NEW``. +Both options can be combined; the prefix map is applied first. + Example --- @@ -532,6 +536,7 @@ For a file called ``/code/library/file.cpp``, here is what would be emitted: * ``-fsanitize-undefined-strip-path-components=2``: ``library/file.cpp`` * ``-fsanitize-undefined-strip-path-components=-1``: ``file.cpp`` * ``-fsanitize-undefined-strip-path-components=-2``: ``library/file.cpp`` +* ``-fsanitize-prefix-map=/code/=``: ``library/file.cpp`` More Information diff --git a/clang/docs/UsersManual.rst b/clang/docs/UsersManual.rst index 3392a210f0bb0..992a5c9337294 100644 --- a/clang/docs/UsersManual.rst +++ b/clang/docs/UsersManual.rst @@
[clang] [llvm] [Clang] Add `-fsanitize-prefix-map` for remapping source paths in sanitizer metadata (PR #186908)
github-actions[bot] wrote: # :penguin: Linux x64 Test Results * 175138 tests passed * 3434 tests skipped * 6 tests failed ## Failed Tests (click on a test name to see its output) ### lldb-api lldb-api.iohandler/sigint/TestProcessIOHandlerInterrupt.py ``` Script: -- /usr/bin/python3 /home/gha/actions-runner/_work/llvm-project/llvm-project/lldb/test/API/dotest.py -u CXXFLAGS -u CFLAGS --env LLVM_LIBS_DIR=/home/gha/actions-runner/_work/llvm-project/llvm-project/build/./lib --env LLVM_INCLUDE_DIR=/home/gha/actions-runner/_work/llvm-project/llvm-project/build/include --env LLVM_TOOLS_DIR=/home/gha/actions-runner/_work/llvm-project/llvm-project/build/./bin --libcxx-include-dir /home/gha/actions-runner/_work/llvm-project/llvm-project/build/include/c++/v1 --libcxx-include-target-dir /home/gha/actions-runner/_work/llvm-project/llvm-project/build/include/x86_64-unknown-linux-gnu/c++/v1 --libcxx-library-dir /home/gha/actions-runner/_work/llvm-project/llvm-project/build/./lib/x86_64-unknown-linux-gnu --triple x86_64-unknown-linux-gnu --build-dir /home/gha/actions-runner/_work/llvm-project/llvm-project/build/lldb-test-build.noindex --lldb-module-cache-dir /home/gha/actions-runner/_work/llvm-project/llvm-project/build/lldb-test-build.noindex/module-cache-lldb/lldb-api --clang-module-cache-dir /home/gha/actions-runner/_work/llvm-project/llvm-project/build/lldb-test-build.noindex/module-cache-clang/lldb-api --executable /home/gha/actions-runner/_work/llvm-project/llvm-project/build/./bin/lldb --compiler /home/gha/actions-runner/_work/llvm-project/llvm-project/build/./bin/clang --dsymutil /home/gha/actions-runner/_work/llvm-project/llvm-project/build/./bin/dsymutil --make /usr/bin/gmake --llvm-tools-dir /home/gha/actions-runner/_work/llvm-project/llvm-project/build/./bin --lldb-obj-root /home/gha/actions-runner/_work/llvm-project/llvm-project/build/tools/lldb --lldb-libs-dir /home/gha/actions-runner/_work/llvm-project/llvm-project/build/./lib --cmake-build-type Release /home/gha/actions-runner/_work/llvm-project/llvm-project/lldb/test/API/iohandler/sigint -p TestProcessIOHandlerInterrupt.py -- Exit Code: 1 Command Output (stdout): -- lldb version 23.0.0git (https://github.com/llvm/llvm-project revision 92b5e6dc749db782887e7d9825302ada71f8c7bb) clang revision 92b5e6dc749db782887e7d9825302ada71f8c7bb llvm revision 92b5e6dc749db782887e7d9825302ada71f8c7bb Skipping the following test categories: msvcstl, dsym, pdb, gmodules, debugserver, objc -- Command Output (stderr): -- FAIL: LLDB (/home/gha/actions-runner/_work/llvm-project/llvm-project/build/bin/clang-x86_64) :: test (TestProcessIOHandlerInterrupt.TestCase.test) Log Files: - /home/gha/actions-runner/_work/llvm-project/llvm-project/build/lldb-test-build.noindex/iohandler/sigint/TestProcessIOHandlerInterrupt.test/Error_test.log == ERROR: test (TestProcessIOHandlerInterrupt.TestCase.test) -- Error when building test subject. Build Command: /usr/bin/gmake VPATH=/home/gha/actions-runner/_work/llvm-project/llvm-project/lldb/test/API/iohandler/sigint -C /home/gha/actions-runner/_work/llvm-project/llvm-project/build/lldb-test-build.noindex/iohandler/sigint/TestProcessIOHandlerInterrupt.test -I /home/gha/actions-runner/_work/llvm-project/llvm-project/lldb/test/API/iohandler/sigint -I /home/gha/actions-runner/_work/llvm-project/llvm-project/lldb/packages/Python/lldbsuite/test/make -f /home/gha/actions-runner/_work/llvm-project/llvm-project/lldb/test/API/iohandler/sigint/Makefile all TRIPLE=x86_64-unknown-linux-gnu CC=/home/gha/actions-runner/_work/llvm-project/llvm-project/build/bin/clang CC_TYPE=clang CXX=/home/gha/actions-runner/_work/llvm-project/llvm-project/build/bin/clang++ LLVM_AR=/home/gha/actions-runner/_work/llvm-project/llvm-project/build/./bin/llvm-ar AR=/home/gha/actions-runner/_work/llvm-project/llvm-project/build/./bin/llvm-ar OBJCOPY=/home/gha/actions-runner/_work/llvm-project/llvm-project/build/./bin/llvm-objcopy STRIP=/home/gha/actions-runner/_work/llvm-project/llvm-project/build/./bin/llvm-strip ARCHIVER=/home/gha/actions-runner/_work/llvm-project/llvm-project/build/./bin/llvm-ar DWP=/home/gha/actions-runner/_work/llvm-project/llvm-project/build/./bin/llvm-dwp CLANG_MODULE_CACHE_DIR=/home/gha/actions-runner/_work/llvm-project/llvm-project/build/lldb-test-build.noindex/module-cache-clang/lldb-api LIBCPP_INCLUDE_DIR=/home/gha/actions-runner/_work/llvm-project/llvm-project/build/include/c++/v1 LIBCPP_LIBRARY_DIR=/home/gha/actions-runner/_work/llvm-project/llvm-project/build/./lib/x86_64-unknown-linux-gnu LIBCPP_INCLUDE_TARGET_DIR=/home/gha/actions-runner/_work/llvm-project/llvm-project/build/include/x86_64-unknown-linux-gnu/c++/v1 LLDB_OBJ_ROOT=/home/gha/actions-runner/_work/llvm-project/llvm-project/build/tools/lldb CXX_SOURCES=cat.cpp
[clang] [llvm] [Clang] Add `-fsanitize-prefix-map` for remapping source paths in sanitizer metadata (PR #186908)
bjosv wrote: Thanks @petrhosek for the suggestion (and sorry for the late response..) I created the PR #201803 with the flag `-fsanitize-compilation-dir=` as suggested, it it like what you had in mind? https://github.com/llvm/llvm-project/pull/186908 ___ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [Clang] Add `-fsanitize-prefix-map` for remapping source paths in sanitizer metadata (PR #186908)
https://github.com/bjosv updated https://github.com/llvm/llvm-project/pull/186908 From 99edbcc918d9032b163bfac8afa5392f3abf1600 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Svensson?= Date: Mon, 16 Mar 2026 20:07:40 +0100 Subject: [PATCH] [Clang] Add -fsanitize-prefix-map= to remap source paths in sanitizer metadata MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add a new option -fsanitize-prefix-map=OLD=NEW that remaps file paths embedded in sanitizer metadata (ASan global module names and UBSan source locations). This enables reproducible builds when source trees reside at different absolute paths. The flag is also implied by -ffile-prefix-map=, consistent with how -fcoverage-prefix-map and -fmacro-prefix-map already work. Signed-off-by: Björn Svensson --- clang/docs/AddressSanitizer.rst | 22 clang/docs/ReleaseNotes.rst | 4 +++ clang/docs/UndefinedBehaviorSanitizer.rst | 5 +++ clang/docs/UsersManual.rst| 2 ++ clang/include/clang/Basic/CodeGenOptions.h| 3 ++ clang/include/clang/Options/Options.td| 5 +++ clang/lib/CodeGen/BackendUtil.cpp | 2 ++ clang/lib/CodeGen/CGExpr.cpp | 9 + clang/lib/Driver/ToolChains/Clang.cpp | 16 + clang/lib/Frontend/CompilerInvocation.cpp | 9 + clang/test/CodeGen/asan-prefix-map.cpp| 12 +++ clang/test/CodeGen/ubsan-prefix-map.cpp | 10 ++ clang/test/Driver/fsanitize-prefix-map.cpp| 8 + .../Instrumentation/AddressSanitizer.h| 1 + .../Instrumentation/AddressSanitizer.cpp | 34 ++- 15 files changed, 134 insertions(+), 8 deletions(-) create mode 100644 clang/test/CodeGen/asan-prefix-map.cpp create mode 100644 clang/test/CodeGen/ubsan-prefix-map.cpp create mode 100644 clang/test/Driver/fsanitize-prefix-map.cpp diff --git a/clang/docs/AddressSanitizer.rst b/clang/docs/AddressSanitizer.rst index 80b1cdd95d77a..a007e86115caa 100644 --- a/clang/docs/AddressSanitizer.rst +++ b/clang/docs/AddressSanitizer.rst @@ -408,6 +408,28 @@ run-time performance, which leads to increased binary size. Using the flag forces all code instrumentation to be outlined, which reduces the size of the generated code, but also reduces the run-time performance. +Remapping source paths +-- + +AddressSanitizer embeds the source file path in global metadata. For +reproducible builds, the option ``-fsanitize-prefix-map=OLD=NEW`` can be used +to remap these paths. If a source path starts with ``OLD``, it will be replaced +with ``NEW``. + +Example +^^^ + +.. code-block:: console + + # Strip build directory prefix + $ clang -fsanitize=address -fsanitize-prefix-map=/build/dir/= source.c + + # Remap to a canonical path + $ clang -fsanitize=address -fsanitize-prefix-map=/home/user/project=/src source.c + +Multiple ``-fsanitize-prefix-map`` options can be specified; the first matching +prefix wins. + Limitations === diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 9e4a47a5b18fc..0eae7ce0d606f 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -929,6 +929,10 @@ Sanitizers -- - UndefinedBehaviorSanitizer now supports ``__ubsan_default_suppressions``. +- Added ``-fsanitize-prefix-map=OLD=NEW`` option to remap source file paths + in sanitizer metadata, enabling reproducible builds. This flag is also + implied by ``-ffile-prefix-map``. + Python Binding Changes -- - Add deprecation warnings to ``CompletionChunk.isKind...`` methods. diff --git a/clang/docs/UndefinedBehaviorSanitizer.rst b/clang/docs/UndefinedBehaviorSanitizer.rst index 3ff1a77e33a6c..683044f621e74 100644 --- a/clang/docs/UndefinedBehaviorSanitizer.rst +++ b/clang/docs/UndefinedBehaviorSanitizer.rst @@ -522,6 +522,10 @@ information. If ``N`` is positive, file information emitted by UndefinedBehaviorSanitizer will drop the first ``N`` components from the file path. If ``N`` is negative, the last ``N`` components will be kept. +Alternatively, ``-fsanitize-prefix-map=OLD=NEW`` can be used to remap file +paths. If a source path starts with ``OLD``, it will be replaced with ``NEW``. +Both options can be combined; the prefix map is applied first. + Example --- @@ -532,6 +536,7 @@ For a file called ``/code/library/file.cpp``, here is what would be emitted: * ``-fsanitize-undefined-strip-path-components=2``: ``library/file.cpp`` * ``-fsanitize-undefined-strip-path-components=-1``: ``file.cpp`` * ``-fsanitize-undefined-strip-path-components=-2``: ``library/file.cpp`` +* ``-fsanitize-prefix-map=/code/=``: ``library/file.cpp`` More Information diff --git a/clang/docs/UsersManual.rst b/clang/docs/UsersManual.rst index 3392a210f0bb0..992a5c9337294 100644 --- a/clang/docs/UsersManual.rst +++ b/clang/docs/UsersManual.rst @@
[clang] [llvm] [Clang] Add `-fsanitize-prefix-map` for remapping source paths in sanitizer metadata (PR #186908)
https://github.com/bjosv updated
https://github.com/llvm/llvm-project/pull/186908
From bdb805470353fc331e7d701edb12b9c538bb1e95 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bj=C3=B6rn=20Svensson?=
Date: Mon, 16 Mar 2026 20:07:40 +0100
Subject: [PATCH 01/11] Add flag -fsanitize-prefix-map==
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Signed-off-by: Björn Svensson
---
clang/include/clang/Options/Options.td | 5 +
clang/lib/Driver/ToolChains/Clang.cpp | 15 +++
clang/test/Driver/fsanitize-prefix-map.cpp | 2 ++
3 files changed, 22 insertions(+)
create mode 100644 clang/test/Driver/fsanitize-prefix-map.cpp
diff --git a/clang/include/clang/Options/Options.td
b/clang/include/clang/Options/Options.td
index a274017953b1d..a47219784ad70 100644
--- a/clang/include/clang/Options/Options.td
+++ b/clang/include/clang/Options/Options.td
@@ -4840,6 +4840,11 @@ def fmacro_prefix_map_EQ
Visibility<[ClangOption, CLOption, CC1Option]>,
HelpText<"remap file source paths in predefined preprocessor macros and "
"__builtin_FILE(). Implies -ffile-reproducible.">;
+def fsanitize_prefix_map_EQ
+ : Joined<["-"], "fsanitize-prefix-map=">, Group,
+Visibility<[ClangOption, CC1Option]>,
+MetaVarName<"=">,
+HelpText<"Remap file source paths in sanitizer metadata">;
defm force_dwarf_frame : BoolFOption<"force-dwarf-frame",
CodeGenOpts<"ForceDwarfFrameSection">, DefaultFalse,
PosFlaggetValue();
+if (!Map.contains('='))
+ D.Diag(diag::err_drv_invalid_argument_to_option)
+ << Map << A->getOption().getName();
+else
+ CmdArgs.push_back(Args.MakeArgString("-fsanitize-prefix-map=" + Map));
+A->claim();
+ }
+}
+
/// Add -x lang to \p CmdArgs for \p Input.
static void addDashXForInput(const ArgList &Args, const InputInfo &Input,
ArgStringList &CmdArgs) {
@@ -1175,6 +1189,7 @@ void Clang::AddPreprocessingOptions(Compilation &C, const
JobAction &JA,
addMacroPrefixMapArg(D, Args, CmdArgs);
addCoveragePrefixMapArg(D, Args, CmdArgs);
+ addSanitizePrefixMapArg(D, Args, CmdArgs);
Args.AddLastArg(CmdArgs, options::OPT_ffile_reproducible,
options::OPT_fno_file_reproducible);
diff --git a/clang/test/Driver/fsanitize-prefix-map.cpp
b/clang/test/Driver/fsanitize-prefix-map.cpp
new file mode 100644
index 0..65f426ec69d5d
--- /dev/null
+++ b/clang/test/Driver/fsanitize-prefix-map.cpp
@@ -0,0 +1,2 @@
+// RUN: %clang %s -### -o %t.o -fsanitize=address
-fsanitize-prefix-map=/old=/new 2>&1 | FileCheck %s
+// CHECK: "-fsanitize-prefix-map=/old=/new"
From 7a8c87297e7453ef42e7d59cbfdb8a21765c63d6 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bj=C3=B6rn=20Svensson?=
Date: Mon, 16 Mar 2026 20:24:42 +0100
Subject: [PATCH 02/11] Add frontend option handling
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Signed-off-by: Björn Svensson
---
clang/include/clang/Basic/CodeGenOptions.h | 3 +++
clang/lib/CodeGen/BackendUtil.cpp | 2 ++
clang/lib/Frontend/CompilerInvocation.cpp | 9 +
3 files changed, 14 insertions(+)
diff --git a/clang/include/clang/Basic/CodeGenOptions.h
b/clang/include/clang/Basic/CodeGenOptions.h
index 8ef0d87faaeaf..73c475dd26c20 100644
--- a/clang/include/clang/Basic/CodeGenOptions.h
+++ b/clang/include/clang/Basic/CodeGenOptions.h
@@ -261,6 +261,9 @@ class CodeGenOptions : public CodeGenOptionsBase {
/// file paths in coverage mapping.
llvm::SmallVector, 0> CoveragePrefixMap;
+ /// Prefix replacement map for sanitizers to remap source file paths.
+ llvm::SmallVector, 0> SanitizePrefixMap;
+
/// The ABI to use for passing floating point arguments.
std::string FloatABI;
diff --git a/clang/lib/CodeGen/BackendUtil.cpp
b/clang/lib/CodeGen/BackendUtil.cpp
index 94257fb96fc7f..e9240b4e1e5ef 100644
--- a/clang/lib/CodeGen/BackendUtil.cpp
+++ b/clang/lib/CodeGen/BackendUtil.cpp
@@ -745,6 +745,8 @@ static void addSanitizers(const Triple &TargetTriple,
Opts.Recover = CodeGenOpts.SanitizeRecover.has(Mask);
Opts.UseAfterScope = CodeGenOpts.SanitizeAddressUseAfterScope;
Opts.UseAfterReturn = CodeGenOpts.getSanitizeAddressUseAfterReturn();
+for (const auto &P : CodeGenOpts.SanitizePrefixMap)
+ Opts.PrefixMap.push_back({P.first, P.second});
MPM.addPass(AddressSanitizerPass(Opts, UseGlobalGC, UseOdrIndicator,
DestructorKind));
}
diff --git a/clang/lib/Frontend/CompilerInvocation.cpp
b/clang/lib/Frontend/CompilerInvocation.cpp
index 6aa2afb6f5918..3a5abd970e055 100644
--- a/clang/lib/Frontend/CompilerInvocation.cpp
+++ b/clang/lib/Frontend/CompilerInvocation.cpp
@@ -1586,6 +1586,10 @@ void CompilerInvocationBase::GenerateCodeGenArgs(const
CodeGenOptions &Opts,
GenerateArg(Consumer, OPT_fcoverage_prefix_map_EQ,
Prefix.first + "=" +
[clang] [llvm] [Clang] Add `-fsanitize-prefix-map` for remapping source paths in sanitizer metadata (PR #186908)
https://github.com/bjosv updated
https://github.com/llvm/llvm-project/pull/186908
From bdb805470353fc331e7d701edb12b9c538bb1e95 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bj=C3=B6rn=20Svensson?=
Date: Mon, 16 Mar 2026 20:07:40 +0100
Subject: [PATCH 01/10] Add flag -fsanitize-prefix-map==
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Signed-off-by: Björn Svensson
---
clang/include/clang/Options/Options.td | 5 +
clang/lib/Driver/ToolChains/Clang.cpp | 15 +++
clang/test/Driver/fsanitize-prefix-map.cpp | 2 ++
3 files changed, 22 insertions(+)
create mode 100644 clang/test/Driver/fsanitize-prefix-map.cpp
diff --git a/clang/include/clang/Options/Options.td
b/clang/include/clang/Options/Options.td
index a274017953b1d..a47219784ad70 100644
--- a/clang/include/clang/Options/Options.td
+++ b/clang/include/clang/Options/Options.td
@@ -4840,6 +4840,11 @@ def fmacro_prefix_map_EQ
Visibility<[ClangOption, CLOption, CC1Option]>,
HelpText<"remap file source paths in predefined preprocessor macros and "
"__builtin_FILE(). Implies -ffile-reproducible.">;
+def fsanitize_prefix_map_EQ
+ : Joined<["-"], "fsanitize-prefix-map=">, Group,
+Visibility<[ClangOption, CC1Option]>,
+MetaVarName<"=">,
+HelpText<"Remap file source paths in sanitizer metadata">;
defm force_dwarf_frame : BoolFOption<"force-dwarf-frame",
CodeGenOpts<"ForceDwarfFrameSection">, DefaultFalse,
PosFlaggetValue();
+if (!Map.contains('='))
+ D.Diag(diag::err_drv_invalid_argument_to_option)
+ << Map << A->getOption().getName();
+else
+ CmdArgs.push_back(Args.MakeArgString("-fsanitize-prefix-map=" + Map));
+A->claim();
+ }
+}
+
/// Add -x lang to \p CmdArgs for \p Input.
static void addDashXForInput(const ArgList &Args, const InputInfo &Input,
ArgStringList &CmdArgs) {
@@ -1175,6 +1189,7 @@ void Clang::AddPreprocessingOptions(Compilation &C, const
JobAction &JA,
addMacroPrefixMapArg(D, Args, CmdArgs);
addCoveragePrefixMapArg(D, Args, CmdArgs);
+ addSanitizePrefixMapArg(D, Args, CmdArgs);
Args.AddLastArg(CmdArgs, options::OPT_ffile_reproducible,
options::OPT_fno_file_reproducible);
diff --git a/clang/test/Driver/fsanitize-prefix-map.cpp
b/clang/test/Driver/fsanitize-prefix-map.cpp
new file mode 100644
index 0..65f426ec69d5d
--- /dev/null
+++ b/clang/test/Driver/fsanitize-prefix-map.cpp
@@ -0,0 +1,2 @@
+// RUN: %clang %s -### -o %t.o -fsanitize=address
-fsanitize-prefix-map=/old=/new 2>&1 | FileCheck %s
+// CHECK: "-fsanitize-prefix-map=/old=/new"
From 7a8c87297e7453ef42e7d59cbfdb8a21765c63d6 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bj=C3=B6rn=20Svensson?=
Date: Mon, 16 Mar 2026 20:24:42 +0100
Subject: [PATCH 02/10] Add frontend option handling
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Signed-off-by: Björn Svensson
---
clang/include/clang/Basic/CodeGenOptions.h | 3 +++
clang/lib/CodeGen/BackendUtil.cpp | 2 ++
clang/lib/Frontend/CompilerInvocation.cpp | 9 +
3 files changed, 14 insertions(+)
diff --git a/clang/include/clang/Basic/CodeGenOptions.h
b/clang/include/clang/Basic/CodeGenOptions.h
index 8ef0d87faaeaf..73c475dd26c20 100644
--- a/clang/include/clang/Basic/CodeGenOptions.h
+++ b/clang/include/clang/Basic/CodeGenOptions.h
@@ -261,6 +261,9 @@ class CodeGenOptions : public CodeGenOptionsBase {
/// file paths in coverage mapping.
llvm::SmallVector, 0> CoveragePrefixMap;
+ /// Prefix replacement map for sanitizers to remap source file paths.
+ llvm::SmallVector, 0> SanitizePrefixMap;
+
/// The ABI to use for passing floating point arguments.
std::string FloatABI;
diff --git a/clang/lib/CodeGen/BackendUtil.cpp
b/clang/lib/CodeGen/BackendUtil.cpp
index 94257fb96fc7f..e9240b4e1e5ef 100644
--- a/clang/lib/CodeGen/BackendUtil.cpp
+++ b/clang/lib/CodeGen/BackendUtil.cpp
@@ -745,6 +745,8 @@ static void addSanitizers(const Triple &TargetTriple,
Opts.Recover = CodeGenOpts.SanitizeRecover.has(Mask);
Opts.UseAfterScope = CodeGenOpts.SanitizeAddressUseAfterScope;
Opts.UseAfterReturn = CodeGenOpts.getSanitizeAddressUseAfterReturn();
+for (const auto &P : CodeGenOpts.SanitizePrefixMap)
+ Opts.PrefixMap.push_back({P.first, P.second});
MPM.addPass(AddressSanitizerPass(Opts, UseGlobalGC, UseOdrIndicator,
DestructorKind));
}
diff --git a/clang/lib/Frontend/CompilerInvocation.cpp
b/clang/lib/Frontend/CompilerInvocation.cpp
index 6aa2afb6f5918..3a5abd970e055 100644
--- a/clang/lib/Frontend/CompilerInvocation.cpp
+++ b/clang/lib/Frontend/CompilerInvocation.cpp
@@ -1586,6 +1586,10 @@ void CompilerInvocationBase::GenerateCodeGenArgs(const
CodeGenOptions &Opts,
GenerateArg(Consumer, OPT_fcoverage_prefix_map_EQ,
Prefix.first + "=" +
[clang] [llvm] [Clang] Add `-fsanitize-prefix-map` for remapping source paths in sanitizer metadata (PR #186908)
https://github.com/bjosv updated
https://github.com/llvm/llvm-project/pull/186908
From bdb805470353fc331e7d701edb12b9c538bb1e95 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bj=C3=B6rn=20Svensson?=
Date: Mon, 16 Mar 2026 20:07:40 +0100
Subject: [PATCH 1/8] Add flag -fsanitize-prefix-map==
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Signed-off-by: Björn Svensson
---
clang/include/clang/Options/Options.td | 5 +
clang/lib/Driver/ToolChains/Clang.cpp | 15 +++
clang/test/Driver/fsanitize-prefix-map.cpp | 2 ++
3 files changed, 22 insertions(+)
create mode 100644 clang/test/Driver/fsanitize-prefix-map.cpp
diff --git a/clang/include/clang/Options/Options.td
b/clang/include/clang/Options/Options.td
index a274017953b1d..a47219784ad70 100644
--- a/clang/include/clang/Options/Options.td
+++ b/clang/include/clang/Options/Options.td
@@ -4840,6 +4840,11 @@ def fmacro_prefix_map_EQ
Visibility<[ClangOption, CLOption, CC1Option]>,
HelpText<"remap file source paths in predefined preprocessor macros and "
"__builtin_FILE(). Implies -ffile-reproducible.">;
+def fsanitize_prefix_map_EQ
+ : Joined<["-"], "fsanitize-prefix-map=">, Group,
+Visibility<[ClangOption, CC1Option]>,
+MetaVarName<"=">,
+HelpText<"Remap file source paths in sanitizer metadata">;
defm force_dwarf_frame : BoolFOption<"force-dwarf-frame",
CodeGenOpts<"ForceDwarfFrameSection">, DefaultFalse,
PosFlaggetValue();
+if (!Map.contains('='))
+ D.Diag(diag::err_drv_invalid_argument_to_option)
+ << Map << A->getOption().getName();
+else
+ CmdArgs.push_back(Args.MakeArgString("-fsanitize-prefix-map=" + Map));
+A->claim();
+ }
+}
+
/// Add -x lang to \p CmdArgs for \p Input.
static void addDashXForInput(const ArgList &Args, const InputInfo &Input,
ArgStringList &CmdArgs) {
@@ -1175,6 +1189,7 @@ void Clang::AddPreprocessingOptions(Compilation &C, const
JobAction &JA,
addMacroPrefixMapArg(D, Args, CmdArgs);
addCoveragePrefixMapArg(D, Args, CmdArgs);
+ addSanitizePrefixMapArg(D, Args, CmdArgs);
Args.AddLastArg(CmdArgs, options::OPT_ffile_reproducible,
options::OPT_fno_file_reproducible);
diff --git a/clang/test/Driver/fsanitize-prefix-map.cpp
b/clang/test/Driver/fsanitize-prefix-map.cpp
new file mode 100644
index 0..65f426ec69d5d
--- /dev/null
+++ b/clang/test/Driver/fsanitize-prefix-map.cpp
@@ -0,0 +1,2 @@
+// RUN: %clang %s -### -o %t.o -fsanitize=address
-fsanitize-prefix-map=/old=/new 2>&1 | FileCheck %s
+// CHECK: "-fsanitize-prefix-map=/old=/new"
From 7a8c87297e7453ef42e7d59cbfdb8a21765c63d6 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bj=C3=B6rn=20Svensson?=
Date: Mon, 16 Mar 2026 20:24:42 +0100
Subject: [PATCH 2/8] Add frontend option handling
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Signed-off-by: Björn Svensson
---
clang/include/clang/Basic/CodeGenOptions.h | 3 +++
clang/lib/CodeGen/BackendUtil.cpp | 2 ++
clang/lib/Frontend/CompilerInvocation.cpp | 9 +
3 files changed, 14 insertions(+)
diff --git a/clang/include/clang/Basic/CodeGenOptions.h
b/clang/include/clang/Basic/CodeGenOptions.h
index 8ef0d87faaeaf..73c475dd26c20 100644
--- a/clang/include/clang/Basic/CodeGenOptions.h
+++ b/clang/include/clang/Basic/CodeGenOptions.h
@@ -261,6 +261,9 @@ class CodeGenOptions : public CodeGenOptionsBase {
/// file paths in coverage mapping.
llvm::SmallVector, 0> CoveragePrefixMap;
+ /// Prefix replacement map for sanitizers to remap source file paths.
+ llvm::SmallVector, 0> SanitizePrefixMap;
+
/// The ABI to use for passing floating point arguments.
std::string FloatABI;
diff --git a/clang/lib/CodeGen/BackendUtil.cpp
b/clang/lib/CodeGen/BackendUtil.cpp
index 94257fb96fc7f..e9240b4e1e5ef 100644
--- a/clang/lib/CodeGen/BackendUtil.cpp
+++ b/clang/lib/CodeGen/BackendUtil.cpp
@@ -745,6 +745,8 @@ static void addSanitizers(const Triple &TargetTriple,
Opts.Recover = CodeGenOpts.SanitizeRecover.has(Mask);
Opts.UseAfterScope = CodeGenOpts.SanitizeAddressUseAfterScope;
Opts.UseAfterReturn = CodeGenOpts.getSanitizeAddressUseAfterReturn();
+for (const auto &P : CodeGenOpts.SanitizePrefixMap)
+ Opts.PrefixMap.push_back({P.first, P.second});
MPM.addPass(AddressSanitizerPass(Opts, UseGlobalGC, UseOdrIndicator,
DestructorKind));
}
diff --git a/clang/lib/Frontend/CompilerInvocation.cpp
b/clang/lib/Frontend/CompilerInvocation.cpp
index 6aa2afb6f5918..3a5abd970e055 100644
--- a/clang/lib/Frontend/CompilerInvocation.cpp
+++ b/clang/lib/Frontend/CompilerInvocation.cpp
@@ -1586,6 +1586,10 @@ void CompilerInvocationBase::GenerateCodeGenArgs(const
CodeGenOptions &Opts,
GenerateArg(Consumer, OPT_fcoverage_prefix_map_EQ,
Prefix.first + "=" +
[clang] [llvm] [Clang] Add `-fsanitize-prefix-map` for remapping source paths in sanitizer metadata (PR #186908)
=?utf-8?q?Björn?= Svensson ,
=?utf-8?q?Björn?= Svensson ,
=?utf-8?q?Björn?= Svensson ,
=?utf-8?q?Björn?= Svensson ,
=?utf-8?q?Björn?= Svensson ,
=?utf-8?q?Björn?= Svensson
Message-ID:
In-Reply-To:
github-actions[bot] wrote:
:warning: C/C++ code formatter, clang-format found issues in your code.
:warning:
You can test this locally with the following command:
``bash
git-clang-format --diff origin/main HEAD --extensions cpp,h --
clang/test/CodeGen/asan-prefix-map.cpp clang/test/CodeGen/ubsan-prefix-map.cpp
clang/test/Driver/fsanitize-prefix-map.cpp
clang/include/clang/Basic/CodeGenOptions.h clang/lib/CodeGen/BackendUtil.cpp
clang/lib/CodeGen/CGExpr.cpp clang/lib/Driver/ToolChains/Clang.cpp
clang/lib/Frontend/CompilerInvocation.cpp
llvm/include/llvm/Transforms/Instrumentation/AddressSanitizer.h
llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
--diff_from_common_commit
``
:warning:
The reproduction instructions above might return results for more than one PR
in a stack if you are using a stacked PR workflow. You can limit the results by
changing `origin/main` to the base branch/commit you want to compare against.
:warning:
View the diff from clang-format here.
``diff
diff --git a/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
b/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
index c762ec883..7ffa4df97 100644
--- a/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
+++ b/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
@@ -2817,9 +2817,9 @@ GlobalVariable
*ModuleAddressSanitizer::getOrCreateModuleName() {
}
}
-ModuleName = createPrivateGlobalForString(M, ModuleNameStr,
- /*AllowMerging*/ false,
- genName("module"));
+ModuleName =
+createPrivateGlobalForString(M, ModuleNameStr,
+ /*AllowMerging*/ false,
genName("module"));
}
return ModuleName;
}
``
https://github.com/llvm/llvm-project/pull/186908
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [Clang] Add `-fsanitize-prefix-map` for remapping source paths in sanitizer metadata (PR #186908)
=?utf-8?q?Björn?= Svensson , =?utf-8?q?Björn?= Svensson , =?utf-8?q?Björn?= Svensson , =?utf-8?q?Björn?= Svensson , =?utf-8?q?Björn?= Svensson , =?utf-8?q?Björn?= Svensson Message-ID: In-Reply-To: llvmbot wrote: @llvm/pr-subscribers-clang-codegen @llvm/pr-subscribers-clang-driver Author: Björn Svensson (bjosv) Changes This adds `-fsanitize-prefix-map=OLD=NEW` to remap file source paths in sanitizer metadata (ASan and UBSan), enabling reproducible builds. AddressSanitizer and UndefinedBehaviorSanitizer embed source file paths in binary metadata (`.rodata`). This causes non-reproducible builds when compiling from different directories. See discussion: https://discourse.llvm.org/t/making-reproducible-builds-using-asan-and-ubsan/89115 While `-fsanitize-undefined-strip-path-components` exists for UBSan, there was no equivalent for ASan, and neither supported path remapping (only stripping). ### Changes - Add `-fsanitize-prefix-map=OLD=NEW` flag - Apply prefix map to ASan module name in `AddressSanitizer.cpp` - Apply prefix map to UBSan source locations in `CGExpr.cpp` - Make `-ffile-prefix-map` imply `-fsanitize-prefix-map` (consistent with debug/macro/coverage prefix maps) ### Usage ```bash # Remap paths for sanitizers only clang -fsanitize=address -fsanitize-prefix-map=/build/dir/= source.c # Or use -ffile-prefix-map (applies to debug info, macros, coverage, and sanitizers) clang -fsanitize=address -ffile-prefix-map=/build/dir/= source.c ``` Alternatively a flag like `-fsanitize-address-strip-path-components=N` can be added instead (`-fsanitize-undefined-strip-path-components` exists already), but this seemed like a better solution. --- Full diff: https://github.com/llvm/llvm-project/pull/186908.diff 15 Files Affected: - (modified) clang/docs/AddressSanitizer.rst (+22) - (modified) clang/docs/ReleaseNotes.rst (+4) - (modified) clang/docs/UndefinedBehaviorSanitizer.rst (+5) - (modified) clang/docs/UsersManual.rst (+2) - (modified) clang/include/clang/Basic/CodeGenOptions.h (+3) - (modified) clang/include/clang/Options/Options.td (+5) - (modified) clang/lib/CodeGen/BackendUtil.cpp (+2) - (modified) clang/lib/CodeGen/CGExpr.cpp (+10) - (modified) clang/lib/Driver/ToolChains/Clang.cpp (+16) - (modified) clang/lib/Frontend/CompilerInvocation.cpp (+9) - (added) clang/test/CodeGen/asan-prefix-map.cpp (+11) - (added) clang/test/CodeGen/ubsan-prefix-map.cpp (+9) - (added) clang/test/Driver/fsanitize-prefix-map.cpp (+8) - (modified) llvm/include/llvm/Transforms/Instrumentation/AddressSanitizer.h (+1) - (modified) llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp (+25-10) ``diff diff --git a/clang/docs/AddressSanitizer.rst b/clang/docs/AddressSanitizer.rst index c11d470d1defa..9a3ca9e53dc4f 100644 --- a/clang/docs/AddressSanitizer.rst +++ b/clang/docs/AddressSanitizer.rst @@ -405,6 +405,28 @@ run-time performance, which leads to increased binary size. Using the flag forces all code instrumentation to be outlined, which reduces the size of the generated code, but also reduces the run-time performance. +Remapping source paths +-- + +AddressSanitizer embeds the source file path in global metadata. For +reproducible builds, the option ``-fsanitize-prefix-map=OLD=NEW`` can be used +to remap these paths. If a source path starts with ``OLD``, it will be replaced +with ``NEW``. + +Example +^^^ + +.. code-block:: console + + # Strip build directory prefix + $ clang -fsanitize=address -fsanitize-prefix-map=/build/dir/= source.c + + # Remap to a canonical path + $ clang -fsanitize=address -fsanitize-prefix-map=/home/user/project=/src source.c + +Multiple ``-fsanitize-prefix-map`` options can be specified; the first matching +prefix wins. + Limitations === diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 557e231a938d9..19002b58b23cc 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -393,6 +393,10 @@ Static Analyzer Sanitizers -- +- Added ``-fsanitize-prefix-map=OLD=NEW`` option to remap source file paths + in sanitizer metadata, enabling reproducible builds. This flag is also + implied by ``-ffile-prefix-map``. + Python Binding Changes -- - Add deprecation warnings to ``CompletionChunk.isKind...`` methods. diff --git a/clang/docs/UndefinedBehaviorSanitizer.rst b/clang/docs/UndefinedBehaviorSanitizer.rst index 60c619daecfc3..218a3855d1ed4 100644 --- a/clang/docs/UndefinedBehaviorSanitizer.rst +++ b/clang/docs/UndefinedBehaviorSanitizer.rst @@ -476,6 +476,10 @@ information. If ``N`` is positive, file information emitted by UndefinedBehaviorSanitizer will drop the first ``N`` components from the file path. If ``N`` is negative, the last ``N`` components will be kept. +Alternatively, ``-fsanitize-prefix-map=OLD=NEW`` can be used to remap file +paths. If a source path starts with ``OLD``, it will be replaced with ``NEW``. +Both
[clang] [llvm] [Clang] Add `-fsanitize-prefix-map` for remapping source paths in sanitizer metadata (PR #186908)
https://github.com/bjosv created
https://github.com/llvm/llvm-project/pull/186908
This adds `-fsanitize-prefix-map=OLD=NEW` to remap file source paths in
sanitizer metadata (ASan and UBSan), enabling reproducible builds.
AddressSanitizer and UndefinedBehaviorSanitizer embed source file paths in
binary metadata (`.rodata`). This causes non-reproducible builds when compiling
from different directories. See discussion:
https://discourse.llvm.org/t/making-reproducible-builds-using-asan-and-ubsan/89115
While `-fsanitize-undefined-strip-path-components` exists for UBSan, there was
no equivalent for ASan, and neither supported path remapping (only stripping).
### Changes
- Add `-fsanitize-prefix-map=OLD=NEW` flag
- Apply prefix map to ASan module name in `AddressSanitizer.cpp`
- Apply prefix map to UBSan source locations in `CGExpr.cpp`
- Make `-ffile-prefix-map` imply `-fsanitize-prefix-map` (consistent with
debug/macro/coverage prefix maps)
### Usage
```bash
# Remap paths for sanitizers only
clang -fsanitize=address -fsanitize-prefix-map=/build/dir/= source.c
# Or use -ffile-prefix-map (applies to debug info, macros, coverage, and
sanitizers)
clang -fsanitize=address -ffile-prefix-map=/build/dir/= source.c
```
Alternatively a flag like `-fsanitize-address-strip-path-components=N` can be
added instead (`-fsanitize-undefined-strip-path-components` exists already),
but this seemed like a better solution.
From bdb805470353fc331e7d701edb12b9c538bb1e95 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bj=C3=B6rn=20Svensson?=
Date: Mon, 16 Mar 2026 20:07:40 +0100
Subject: [PATCH 1/7] Add flag -fsanitize-prefix-map==
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Signed-off-by: Björn Svensson
---
clang/include/clang/Options/Options.td | 5 +
clang/lib/Driver/ToolChains/Clang.cpp | 15 +++
clang/test/Driver/fsanitize-prefix-map.cpp | 2 ++
3 files changed, 22 insertions(+)
create mode 100644 clang/test/Driver/fsanitize-prefix-map.cpp
diff --git a/clang/include/clang/Options/Options.td
b/clang/include/clang/Options/Options.td
index a274017953b1d..a47219784ad70 100644
--- a/clang/include/clang/Options/Options.td
+++ b/clang/include/clang/Options/Options.td
@@ -4840,6 +4840,11 @@ def fmacro_prefix_map_EQ
Visibility<[ClangOption, CLOption, CC1Option]>,
HelpText<"remap file source paths in predefined preprocessor macros and "
"__builtin_FILE(). Implies -ffile-reproducible.">;
+def fsanitize_prefix_map_EQ
+ : Joined<["-"], "fsanitize-prefix-map=">, Group,
+Visibility<[ClangOption, CC1Option]>,
+MetaVarName<"=">,
+HelpText<"Remap file source paths in sanitizer metadata">;
defm force_dwarf_frame : BoolFOption<"force-dwarf-frame",
CodeGenOpts<"ForceDwarfFrameSection">, DefaultFalse,
PosFlaggetValue();
+if (!Map.contains('='))
+ D.Diag(diag::err_drv_invalid_argument_to_option)
+ << Map << A->getOption().getName();
+else
+ CmdArgs.push_back(Args.MakeArgString("-fsanitize-prefix-map=" + Map));
+A->claim();
+ }
+}
+
/// Add -x lang to \p CmdArgs for \p Input.
static void addDashXForInput(const ArgList &Args, const InputInfo &Input,
ArgStringList &CmdArgs) {
@@ -1175,6 +1189,7 @@ void Clang::AddPreprocessingOptions(Compilation &C, const
JobAction &JA,
addMacroPrefixMapArg(D, Args, CmdArgs);
addCoveragePrefixMapArg(D, Args, CmdArgs);
+ addSanitizePrefixMapArg(D, Args, CmdArgs);
Args.AddLastArg(CmdArgs, options::OPT_ffile_reproducible,
options::OPT_fno_file_reproducible);
diff --git a/clang/test/Driver/fsanitize-prefix-map.cpp
b/clang/test/Driver/fsanitize-prefix-map.cpp
new file mode 100644
index 0..65f426ec69d5d
--- /dev/null
+++ b/clang/test/Driver/fsanitize-prefix-map.cpp
@@ -0,0 +1,2 @@
+// RUN: %clang %s -### -o %t.o -fsanitize=address
-fsanitize-prefix-map=/old=/new 2>&1 | FileCheck %s
+// CHECK: "-fsanitize-prefix-map=/old=/new"
From 7a8c87297e7453ef42e7d59cbfdb8a21765c63d6 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bj=C3=B6rn=20Svensson?=
Date: Mon, 16 Mar 2026 20:24:42 +0100
Subject: [PATCH 2/7] Add frontend option handling
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Signed-off-by: Björn Svensson
---
clang/include/clang/Basic/CodeGenOptions.h | 3 +++
clang/lib/CodeGen/BackendUtil.cpp | 2 ++
clang/lib/Frontend/CompilerInvocation.cpp | 9 +
3 files changed, 14 insertions(+)
diff --git a/clang/include/clang/Basic/CodeGenOptions.h
b/clang/include/clang/Basic/CodeGenOptions.h
index 8ef0d87faaeaf..73c475dd26c20 100644
--- a/clang/include/clang/Basic/CodeGenOptions.h
+++ b/clang/include/clang/Basic/CodeGenOptions.h
@@ -261,6 +261,9 @@ class CodeGenOptions : public CodeGenOptionsBase {
/// file paths in coverage mapping.
llvm::SmallVector, 0> CoveragePrefixMap;
+ /// Prefix replacement map for sanitizers to remap
