[llvm] [CMake][ASAN] Add support for ADDRESS_SANITIZER_BUILD compile option (PR #83595)
Christian Ulmann via llvm-commits
llvm-commits at lists.llvm.org
Wed Sep 11 07:16:42 PDT 2024
https://github.com/Dinistro updated https://github.com/llvm/llvm-project/pull/83595
>From aa2a5abff7b3c7790f4863abae504f3cd426b35b Mon Sep 17 00:00:00 2001
From: Christian Ulmann <christian.ulmann at nextsilicon.com>
Date: Fri, 1 Mar 2024 16:50:30 +0000
Subject: [PATCH 1/2] [CMake][ASAN] Add support for ADDRESS_SANITIZER_BUILD
compile option
This commit introduces the `LLVM_ADDRESS_SANITIZER_BUILD` compile option
that is set to indicate if LLVM has been built with ASAN enabled or not.
This is a necessary addition to properly control the declarations of
`__asan_*` helpers in header files. Previously, some of these
declarations relied on `__has_feature(address_sanitizer)`, which can
lead to differences between in-tree compilation units and down-stream
usages of the same headers.
The reproducer of this issue involved templates, which then lead to
violation of the ODR due to having two different instances of the same
template.
---
llvm/cmake/modules/HandleLLVMOptions.cmake | 13 +++++++++++++
llvm/include/llvm/Support/Compiler.h | 7 ++++---
2 files changed, 17 insertions(+), 3 deletions(-)
diff --git a/llvm/cmake/modules/HandleLLVMOptions.cmake b/llvm/cmake/modules/HandleLLVMOptions.cmake
index 08ff49ded57a14..cec18e3a4a734a 100644
--- a/llvm/cmake/modules/HandleLLVMOptions.cmake
+++ b/llvm/cmake/modules/HandleLLVMOptions.cmake
@@ -940,6 +940,7 @@ if(LLVM_USE_SANITIZER)
if (LLVM_USE_SANITIZER STREQUAL "Address")
append_common_sanitizer_flags()
append("-fsanitize=address" CMAKE_C_FLAGS CMAKE_CXX_FLAGS)
+ set(LLVM_ADDRESS_SANITIZER_BUILD ON)
elseif (LLVM_USE_SANITIZER STREQUAL "HWAddress")
append_common_sanitizer_flags()
append("-fsanitize=hwaddress" CMAKE_C_FLAGS CMAKE_CXX_FLAGS)
@@ -961,6 +962,7 @@ if(LLVM_USE_SANITIZER)
LLVM_USE_SANITIZER STREQUAL "Undefined;Address")
append_common_sanitizer_flags()
append("-fsanitize=address" CMAKE_C_FLAGS CMAKE_CXX_FLAGS)
+ set(LLVM_ADDRESS_SANITIZER_BUILD ON)
append("${LLVM_UBSAN_FLAGS}" CMAKE_C_FLAGS CMAKE_CXX_FLAGS)
elseif (LLVM_USE_SANITIZER STREQUAL "Leaks")
append_common_sanitizer_flags()
@@ -972,6 +974,7 @@ if(LLVM_USE_SANITIZER)
if (LLVM_USE_SANITIZER STREQUAL "Address")
append_common_sanitizer_flags()
append("-fsanitize=address" CMAKE_C_FLAGS CMAKE_CXX_FLAGS)
+ set(LLVM_ADDRESS_SANITIZER_BUILD ON)
elseif (LLVM_USE_SANITIZER STREQUAL "Undefined")
append_common_sanitizer_flags()
append("${LLVM_UBSAN_FLAGS}" CMAKE_C_FLAGS CMAKE_CXX_FLAGS)
@@ -979,6 +982,7 @@ if(LLVM_USE_SANITIZER)
LLVM_USE_SANITIZER STREQUAL "Undefined;Address")
append_common_sanitizer_flags()
append("-fsanitize=address" CMAKE_C_FLAGS CMAKE_CXX_FLAGS)
+ set(LLVM_ADDRESS_SANITIZER_BUILD ON)
append("${LLVM_UBSAN_FLAGS}" CMAKE_C_FLAGS CMAKE_CXX_FLAGS)
else()
message(FATAL_ERROR "This sanitizer not yet supported in a MinGW environment: ${LLVM_USE_SANITIZER}")
@@ -1008,11 +1012,13 @@ if(LLVM_USE_SANITIZER)
append("clang_rt.asan_dynamic-${arch}.lib /wholearchive:clang_rt.asan_dynamic_runtime_thunk-${arch}.lib"
CMAKE_EXE_LINKER_FLAGS CMAKE_MODULE_LINKER_FLAGS CMAKE_SHARED_LINKER_FLAGS)
endif()
+ set(LLVM_ADDRESS_SANITIZER_BUILD ON)
endif()
endif()
if (LLVM_USE_SANITIZER MATCHES ".*Address.*")
if (NOT CLANG_CL)
append("/fsanitize=address" CMAKE_C_FLAGS CMAKE_CXX_FLAGS)
+ set(LLVM_ADDRESS_SANITIZER_BUILD ON)
# Not compatible with /RTC flags.
foreach (flags_opt_to_scrub
CMAKE_CXX_FLAGS_${uppercase_CMAKE_BUILD_TYPE} CMAKE_C_FLAGS_${uppercase_CMAKE_BUILD_TYPE})
@@ -1046,6 +1052,13 @@ if(LLVM_USE_SANITIZER)
endif()
endif()
+# Add a compile option to indicate if LLVM is building with address sanitizers.
+if(LLVM_ADDRESS_SANITIZER_BUILD)
+ add_compile_definitions(LLVM_ADDRESS_SANITIZER_BUILD=1)
+else()
+ add_compile_definitions(LLVM_ADDRESS_SANITIZER_BUILD=0)
+endif()
+
# Turn on -gsplit-dwarf if requested in debug builds.
if (LLVM_USE_SPLIT_DWARF AND
((uppercase_CMAKE_BUILD_TYPE STREQUAL "DEBUG") OR
diff --git a/llvm/include/llvm/Support/Compiler.h b/llvm/include/llvm/Support/Compiler.h
index 8c315d255bb772..42121289864419 100644
--- a/llvm/include/llvm/Support/Compiler.h
+++ b/llvm/include/llvm/Support/Compiler.h
@@ -438,8 +438,10 @@
/// \macro LLVM_ADDRESS_SANITIZER_BUILD
/// Whether LLVM itself is built with AddressSanitizer instrumentation.
-#if __has_feature(address_sanitizer) || defined(__SANITIZE_ADDRESS__)
-# define LLVM_ADDRESS_SANITIZER_BUILD 1
+#ifndef LLVM_ADDRESS_SANITIZER_BUILD
+# define LLVM_ADDRESS_SANITIZER_BUILD 0
+#endif
+#if LLVM_ADDRESS_SANITIZER_BUILD
#if __has_include(<sanitizer/asan_interface.h>)
# include <sanitizer/asan_interface.h>
#else
@@ -455,7 +457,6 @@ void __asan_unpoison_memory_region(void const volatile *addr, size_t size);
#endif
#endif
#else
-# define LLVM_ADDRESS_SANITIZER_BUILD 0
# define __asan_poison_memory_region(p, size)
# define __asan_unpoison_memory_region(p, size)
#endif
>From 9ac511312d7f458367fc72b6ac9ec304b1574fc8 Mon Sep 17 00:00:00 2001
From: Christian Ulmann <christianulmann at gmail.com>
Date: Wed, 11 Sep 2024 16:11:10 +0200
Subject: [PATCH 2/2] add #error for ASAN mismatch with DYLIB off
---
llvm/cmake/modules/HandleLLVMOptions.cmake | 7 -------
llvm/include/llvm/Config/llvm-config.h.cmake | 3 +++
llvm/include/llvm/Support/Compiler.h | 14 +++++++++-----
3 files changed, 12 insertions(+), 12 deletions(-)
diff --git a/llvm/cmake/modules/HandleLLVMOptions.cmake b/llvm/cmake/modules/HandleLLVMOptions.cmake
index cec18e3a4a734a..f36df8bddf0067 100644
--- a/llvm/cmake/modules/HandleLLVMOptions.cmake
+++ b/llvm/cmake/modules/HandleLLVMOptions.cmake
@@ -1052,13 +1052,6 @@ if(LLVM_USE_SANITIZER)
endif()
endif()
-# Add a compile option to indicate if LLVM is building with address sanitizers.
-if(LLVM_ADDRESS_SANITIZER_BUILD)
- add_compile_definitions(LLVM_ADDRESS_SANITIZER_BUILD=1)
-else()
- add_compile_definitions(LLVM_ADDRESS_SANITIZER_BUILD=0)
-endif()
-
# Turn on -gsplit-dwarf if requested in debug builds.
if (LLVM_USE_SPLIT_DWARF AND
((uppercase_CMAKE_BUILD_TYPE STREQUAL "DEBUG") OR
diff --git a/llvm/include/llvm/Config/llvm-config.h.cmake b/llvm/include/llvm/Config/llvm-config.h.cmake
index 6605ea60df99e1..f026d3826f4d51 100644
--- a/llvm/include/llvm/Config/llvm-config.h.cmake
+++ b/llvm/include/llvm/Config/llvm-config.h.cmake
@@ -198,4 +198,7 @@
/* Define if plugins enabled */
#cmakedefine LLVM_ENABLE_PLUGINS
+/* Define if LLVM is build with address sanitizers enabled */
+#cmakedefine01 LLVM_ADDRESS_SANITIZER_BUILD
+
#endif
diff --git a/llvm/include/llvm/Support/Compiler.h b/llvm/include/llvm/Support/Compiler.h
index 42121289864419..9bb3b907631e18 100644
--- a/llvm/include/llvm/Support/Compiler.h
+++ b/llvm/include/llvm/Support/Compiler.h
@@ -436,12 +436,16 @@
# define LLVM_NO_SANITIZE_MEMORY_ATTRIBUTE
#endif
-/// \macro LLVM_ADDRESS_SANITIZER_BUILD
-/// Whether LLVM itself is built with AddressSanitizer instrumentation.
-#ifndef LLVM_ADDRESS_SANITIZER_BUILD
-# define LLVM_ADDRESS_SANITIZER_BUILD 0
-#endif
#if LLVM_ADDRESS_SANITIZER_BUILD
+
+// These kind of sanitizer mismatches can lead to sporadic false positives that
+// are very hard to debug.
+#if !defined(LLVM_BUILD_LLVM_DYLIB) && \
+ !__has_feature(address_sanitizer) && \
+ !defined(__SANITIZE_ADDRESS__)
+#error An address sanitized LLVM build cannot be combined with unsanitized code.
+#endif
+
#if __has_include(<sanitizer/asan_interface.h>)
# include <sanitizer/asan_interface.h>
#else
More information about the llvm-commits
mailing list