xref: /aosp_15_r20/external/pytorch/cmake/Modules/FindSanitizer.cmake (revision da0073e96a02ea20f0ac840b70461e3646d07c45)
1# Find sanitizers
2#
3# This module sets the following targets:
4#  Sanitizer::address
5#  Sanitizer::thread
6#  Sanitizer::undefined
7#  Sanitizer::leak
8#  Sanitizer::memory
9include_guard(GLOBAL)
10
11option(UBSAN_FLAGS "additional UBSAN flags" OFF)
12
13get_property(languages GLOBAL PROPERTY ENABLED_LANGUAGES)
14
15set(_source_code
16    [==[
17  #include <stdio.h>
18  int main() {
19  printf("hello world!");
20  return 0;
21  }
22  ]==])
23
24include(CMakePushCheckState)
25cmake_push_check_state(RESET)
26foreach(sanitizer_name IN ITEMS address thread undefined leak memory)
27  if(TARGET Sanitizer::${sanitizer_name})
28    continue()
29  endif()
30
31  set(CMAKE_REQUIRED_FLAGS
32      "-fsanitize=${sanitizer_name};-fno-omit-frame-pointer")
33  if(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC" OR CMAKE_C_COMPILER_ID STREQUAL
34                                              "MSVC")
35    if(sanitizer_name STREQUAL "address")
36      set(CMAKE_REQUIRED_FLAGS "/fsanitize=${sanitizer_name}")
37    else()
38      continue()
39    endif()
40  endif()
41  if(sanitizer_name STREQUAL "address")
42    if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang" OR CMAKE_C_COMPILER_ID STREQUAL
43                                                 "Clang")
44      list(APPEND CMAKE_REQUIRED_FLAGS "-shared-libasan")
45    endif()
46  endif()
47  if(sanitizer_name STREQUAL "undefined" AND UBSAN_FLAGS)
48    list(APPEND CMAKE_REQUIRED_FLAGS "${UBSAN_FLAGS}")
49  endif()
50  if(sanitizer_name STREQUAL "memory")
51    list(APPEND CMAKE_REQUIRED_FLAGS "-fsanitize-memory-track-origins=2")
52  endif()
53
54  set(CMAKE_REQUIRED_QUIET ON)
55  set(_run_res 0)
56  include(CheckCSourceRuns)
57  include(CheckCXXSourceRuns)
58  foreach(lang IN LISTS languages)
59    if(lang STREQUAL C)
60      check_c_source_runs("${_source_code}"
61                        __${lang}_${sanitizer_name}_res)
62      if(__${lang}_${sanitizer_name}_res)
63        set(_run_res 1)
64      endif()
65    endif()
66    if(lang STREQUAL CXX)
67      check_cxx_source_runs("${_source_code}"
68                        __${lang}_${sanitizer_name}_res)
69      if(__${lang}_${sanitizer_name}_res)
70        set(_run_res 1)
71      endif()
72    endif()
73  endforeach()
74  if(_run_res)
75    add_library(Sanitizer::${sanitizer_name} INTERFACE IMPORTED GLOBAL)
76    target_compile_options(
77      Sanitizer::${sanitizer_name}
78      INTERFACE
79        $<$<AND:$<COMPILE_LANGUAGE:CXX>,$<BOOL:$__CXX_${sanitizer_name}_res>>:${CMAKE_REQUIRED_FLAGS}>
80        $<$<AND:$<COMPILE_LANGUAGE:C>,$<BOOL:$__C_${sanitizer_name}_res>>:${CMAKE_REQUIRED_FLAGS}>
81    )
82    if(NOT CMAKE_CXX_COMPILER_ID STREQUAL "MSVC" AND NOT CMAKE_C_COMPILER_ID
83                                                     STREQUAL "MSVC")
84      target_link_options(
85        Sanitizer::${sanitizer_name}
86        INTERFACE
87        $<$<AND:$<COMPILE_LANGUAGE:CXX>,$<BOOL:$__CXX_${sanitizer_name}_res>>:${CMAKE_REQUIRED_FLAGS}>
88        $<$<AND:$<COMPILE_LANGUAGE:C>,$<BOOL:$__C_${sanitizer_name}_res>>:${CMAKE_REQUIRED_FLAGS}>
89      )
90    else()
91      target_link_options(
92        Sanitizer::${sanitizer_name}
93        INTERFACE
94        $<$<AND:$<COMPILE_LANGUAGE:CXX>,$<BOOL:$__CXX_${sanitizer_name}_res>>:/INCREMENTAL:NO>
95        $<$<AND:$<COMPILE_LANGUAGE:C>,$<BOOL:$__C_${sanitizer_name}_res>>:/INCREMENTAL:NO>
96      )
97    endif()
98
99    if(sanitizer_name STREQUAL "address")
100      target_compile_definitions(
101        Sanitizer::${sanitizer_name}
102        INTERFACE
103          $<$<AND:$<COMPILE_LANGUAGE:CXX>,$<BOOL:$__CXX_${sanitizer_name}_res>>:_GLIBCXX_SANITIZE_VECTOR>
104          $<$<AND:$<COMPILE_LANGUAGE:CXX>,$<BOOL:$__CXX_${sanitizer_name}_res>>:_GLIBCXX_SANITIZE_STD_ALLOCATOR>
105      )
106      target_link_options(
107        Sanitizer::${sanitizer_name}
108        INTERFACE
109        $<$<AND:$<COMPILE_LANGUAGE:CXX>,$<BOOL:$__CXX_${sanitizer_name}_res>,$<CXX_COMPILER_ID:GNU>>:-lasan>
110        $<$<AND:$<COMPILE_LANGUAGE:C>,$<BOOL:$__C_${sanitizer_name}_res>,$<C_COMPILER_ID:GNU>>:-lasan>
111      )
112    endif()
113    if(sanitizer_name STREQUAL "undefined")
114      target_link_options(
115        Sanitizer::${sanitizer_name}
116        INTERFACE
117        $<$<AND:$<COMPILE_LANGUAGE:CXX>,$<BOOL:$__CXX_${sanitizer_name}_res>,$<CXX_COMPILER_ID:GNU>>:-lubsan>
118        $<$<AND:$<COMPILE_LANGUAGE:C>,$<BOOL:$__C_${sanitizer_name}_res>,$<C_COMPILER_ID:GNU>>:-lubsan>
119      )
120    endif()
121  endif()
122endforeach()
123
124cmake_pop_check_state()
125