[llvm] [CMake][ASAN] Add support for ADDRESS_SANITIZER_BUILD compile option (PR #83595)

via llvm-commits llvm-commits at lists.llvm.org
Sun Aug 4 03:53:22 PDT 2024


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-llvm-support

Author: Christian Ulmann (Dinistro)

<details>
<summary>Changes</summary>

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.

This is a first attempt to resolve https://github.com/llvm/llvm-project/issues/83566, but it might require additional fixes for the other usages of `__has_feature()` in `Compiler.h`.

---
Full diff: https://github.com/llvm/llvm-project/pull/83595.diff


3 Files Affected:

- (modified) llvm/cmake/modules/HandleLLVMOptions.cmake (+13) 
- (modified) llvm/include/llvm/Config/llvm-config.h.cmake (+3) 
- (modified) llvm/include/llvm/Support/Compiler.h (+1-5) 


``````````diff
diff --git a/llvm/cmake/modules/HandleLLVMOptions.cmake b/llvm/cmake/modules/HandleLLVMOptions.cmake
index bdbd36174fc7a..468fe7c60ade1 100644
--- a/llvm/cmake/modules/HandleLLVMOptions.cmake
+++ b/llvm/cmake/modules/HandleLLVMOptions.cmake
@@ -947,6 +947,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)
@@ -968,6 +969,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()
@@ -979,6 +981,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)
@@ -986,6 +989,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}")
@@ -1015,11 +1019,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})
@@ -1053,6 +1059,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/Config/llvm-config.h.cmake b/llvm/include/llvm/Config/llvm-config.h.cmake
index 629977cc11d68..b26ddf707f03a 100644
--- a/llvm/include/llvm/Config/llvm-config.h.cmake
+++ b/llvm/include/llvm/Config/llvm-config.h.cmake
@@ -201,4 +201,7 @@
 /* Define if logf128 is available */
 #cmakedefine LLVM_HAS_LOGF128
 
+/* Define if building LLVM with ASAN */
+#cmakedefine01 LLVM_ADDRESS_SANITIZER_BUILD
+
 #endif
diff --git a/llvm/include/llvm/Support/Compiler.h b/llvm/include/llvm/Support/Compiler.h
index d8e3794babc74..b7667fdfbcf45 100644
--- a/llvm/include/llvm/Support/Compiler.h
+++ b/llvm/include/llvm/Support/Compiler.h
@@ -444,10 +444,7 @@
 # define LLVM_NO_SANITIZE_MEMORY_ATTRIBUTE
 #endif
 
-/// \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
+#if LLVM_ADDRESS_SANITIZER_BUILD
 #if __has_include(<sanitizer/asan_interface.h>)
 # include <sanitizer/asan_interface.h>
 #else
@@ -463,7 +460,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

``````````

</details>


https://github.com/llvm/llvm-project/pull/83595


More information about the llvm-commits mailing list