1include(CompilerRTCompile)
2
3clang_compiler_add_cxx_check()
4
5# FIXME: use SANITIZER_COMMON_SUPPORTED_ARCH here
6filter_available_targets(SANITIZER_UNITTEST_SUPPORTED_ARCH x86_64 i386 mips64 mips64el riscv64 sparcv9 sparc)
7if(APPLE)
8  list(APPEND SANITIZER_UNITTEST_SUPPORTED_ARCH arm64)
9  darwin_filter_host_archs(SANITIZER_UNITTEST_SUPPORTED_ARCH SANITIZER_UNITTEST_SUPPORTED_ARCH)
10endif()
11
12set(SANITIZER_UNITTESTS
13  sanitizer_addrhashmap_test.cpp
14  sanitizer_allocator_test.cpp
15  sanitizer_atomic_test.cpp
16  sanitizer_bitvector_test.cpp
17  sanitizer_bvgraph_test.cpp
18  sanitizer_chained_origin_depot_test.cpp
19  sanitizer_common_test.cpp
20  sanitizer_deadlock_detector_test.cpp
21  sanitizer_dense_map_test.cpp
22  sanitizer_flags_test.cpp
23  sanitizer_flat_map_test.cpp
24  sanitizer_format_interceptor_test.cpp
25  sanitizer_hash_test.cpp
26  sanitizer_ioctl_test.cpp
27  sanitizer_leb128_test.cpp
28  sanitizer_libc_test.cpp
29  sanitizer_linux_test.cpp
30  sanitizer_list_test.cpp
31  sanitizer_lzw_test.cpp
32  sanitizer_mac_test.cpp
33  sanitizer_mutex_test.cpp
34  sanitizer_nolibc_test.cpp
35  sanitizer_posix_test.cpp
36  sanitizer_printf_test.cpp
37  sanitizer_procmaps_test.cpp
38  sanitizer_ring_buffer_test.cpp
39  sanitizer_quarantine_test.cpp
40  sanitizer_stack_store_test.cpp
41  sanitizer_stackdepot_test.cpp
42  sanitizer_stacktrace_printer_test.cpp
43  sanitizer_stacktrace_test.cpp
44  sanitizer_stoptheworld_test.cpp
45  sanitizer_suppressions_test.cpp
46  sanitizer_symbolizer_test.cpp
47  sanitizer_test_main.cpp
48  sanitizer_thread_registry_test.cpp
49  sanitizer_type_traits_test.cpp
50  sanitizer_vector_test.cpp
51  )
52
53set(SANITIZER_TEST_HEADERS
54  sanitizer_pthread_wrappers.h
55  sanitizer_test_config.h
56  sanitizer_test_utils.h
57  )
58foreach(header ${SANITIZER_IMPL_HEADERS})
59  list(APPEND SANITIZER_TEST_HEADERS ${CMAKE_CURRENT_SOURCE_DIR}/../${header})
60endforeach()
61
62set(SANITIZER_TEST_CFLAGS_COMMON
63  ${COMPILER_RT_UNITTEST_CFLAGS}
64  ${COMPILER_RT_GTEST_CFLAGS}
65  ${COMPILER_RT_GMOCK_CFLAGS}
66  ${SANITIZER_TEST_CXX_CFLAGS}
67  -I${COMPILER_RT_SOURCE_DIR}/include
68  -I${COMPILER_RT_SOURCE_DIR}/lib
69  -I${COMPILER_RT_SOURCE_DIR}/lib/sanitizer_common
70  -fno-rtti
71  -O2
72  -Werror=sign-compare
73  -Wno-gnu-zero-variadic-macro-arguments
74  )
75
76set(SANITIZER_TEST_LINK_FLAGS_COMMON
77  ${COMPILER_RT_UNITTEST_LINK_FLAGS}
78  ${COMPILER_RT_UNWINDER_LINK_LIBS}
79  ${SANITIZER_TEST_CXX_LIBRARIES})
80
81# -gline-tables-only must be enough for these tests, so use it if possible.
82if(COMPILER_RT_TEST_COMPILER_ID MATCHES "Clang")
83  list(APPEND SANITIZER_TEST_CFLAGS_COMMON -gline-tables-only)
84else()
85  list(APPEND SANITIZER_TEST_CFLAGS_COMMON -g)
86endif()
87if(MSVC)
88  list(APPEND SANITIZER_TEST_CFLAGS_COMMON -gcodeview)
89endif()
90list(APPEND SANITIZER_TEST_LINK_FLAGS_COMMON -g)
91
92if(NOT MSVC)
93  list(APPEND SANITIZER_TEST_LINK_FLAGS_COMMON --driver-mode=g++)
94endif()
95
96if(ANDROID)
97  list(APPEND SANITIZER_TEST_LINK_FLAGS_COMMON -pie)
98endif()
99
100if(APPLE)
101  list(APPEND SANITIZER_TEST_CFLAGS_COMMON ${DARWIN_osx_CFLAGS})
102  list(APPEND SANITIZER_TEST_LINK_FLAGS_COMMON ${DARWIN_osx_LINK_FLAGS})
103
104  add_weak_symbols("sanitizer_common" WEAK_SYMBOL_LINK_FLAGS)
105  list(APPEND SANITIZER_TEST_LINK_FLAGS_COMMON ${WEAK_SYMBOL_LINK_FLAGS})
106  # For c++17 sanitizer_allocator_test requires language features introduced in macos 10.13
107  list(APPEND SANITIZER_TEST_CFLAGS_COMMON "-mmacosx-version-min=10.13")
108endif()
109
110# MSVC linker is allocating 1M for the stack by default, which is not
111# enough for the unittests. Some unittests require more than 2M.
112# The default stack size for clang is 8M.
113if(MSVC)
114  list(APPEND SANITIZER_TEST_LINK_FLAGS_COMMON -Wl,/STACK:0xC00000)
115endif()
116
117set(SANITIZER_TEST_LINK_LIBS)
118append_list_if(COMPILER_RT_HAS_LIBLOG log SANITIZER_TEST_LINK_LIBS)
119# NDK r10 requires -latomic almost always.
120append_list_if(ANDROID atomic SANITIZER_TEST_LINK_LIBS)
121
122append_list_if(COMPILER_RT_HAS_LIBDL -ldl SANITIZER_TEST_LINK_FLAGS_COMMON)
123append_list_if(COMPILER_RT_HAS_LIBRT -lrt SANITIZER_TEST_LINK_FLAGS_COMMON)
124append_list_if(COMPILER_RT_HAS_LIBPTHREAD -pthread SANITIZER_TEST_LINK_FLAGS_COMMON)
125# x86_64 FreeBSD 9.2 additionally requires libc++ to build the tests. Also,
126# 'libm' shall be specified explicitly to build i386 tests.
127if(CMAKE_SYSTEM MATCHES "FreeBSD-9.2-RELEASE")
128  list(APPEND SANITIZER_TEST_LINK_FLAGS_COMMON "-lc++ -lm")
129endif()
130
131include_directories(..)
132include_directories(../..)
133
134# Adds static library which contains sanitizer_common object file
135# (universal binary on Mac and arch-specific object files on Linux).
136macro(add_sanitizer_common_lib library)
137  add_library(${library} STATIC ${ARGN})
138  set_target_properties(${library} PROPERTIES
139    ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
140    FOLDER "Compiler-RT Runtime tests")
141endmacro()
142
143function(get_sanitizer_common_lib_for_arch arch lib)
144  if(APPLE)
145    set(tgt_name "RTSanitizerCommon.test.osx")
146  else()
147    set(tgt_name "RTSanitizerCommon.test.${arch}")
148  endif()
149  set(${lib} "${tgt_name}" PARENT_SCOPE)
150endfunction()
151
152# Sanitizer_common unit tests testsuite.
153add_custom_target(SanitizerUnitTests)
154set_target_properties(SanitizerUnitTests PROPERTIES FOLDER "Compiler-RT Tests")
155
156# Adds sanitizer tests for architecture.
157macro(add_sanitizer_tests_for_arch arch)
158  set(extra_flags)
159  if( CMAKE_SIZEOF_VOID_P EQUAL 4 )
160    list(APPEND extra_flags "-D_LARGEFILE_SOURCE")
161    list(APPEND extra_flags "-D_FILE_OFFSET_BITS=64")
162  endif()
163  get_sanitizer_common_lib_for_arch(${arch} SANITIZER_COMMON_LIB)
164  set(TARGET_LINK_FLAGS)
165  get_target_link_flags_for_arch(${arch} TARGET_LINK_FLAGS)
166
167  set(SANITIZER_TEST_OBJECTS)
168  generate_compiler_rt_tests(SANITIZER_TEST_OBJECTS SanitizerUnitTests
169    "Sanitizer-${arch}-Test" ${arch}
170    RUNTIME "${SANITIZER_COMMON_LIB}"
171    SOURCES ${SANITIZER_UNITTESTS} ${COMPILER_RT_GTEST_SOURCE} ${COMPILER_RT_GMOCK_SOURCE}
172    COMPILE_DEPS ${SANITIZER_TEST_HEADERS}
173    DEPS llvm_gtest
174    CFLAGS  ${SANITIZER_TEST_CFLAGS_COMMON} ${extra_flags}
175    LINK_FLAGS ${SANITIZER_TEST_LINK_FLAGS_COMMON} ${TARGET_LINK_FLAGS} ${extra_flags})
176
177  if("${CMAKE_SYSTEM_NAME}" STREQUAL "Linux" AND "${arch}" STREQUAL "x86_64")
178    # Test that the libc-independent part of sanitizer_common is indeed
179    # independent of libc, by linking this binary without libc (here) and
180    # executing it (unit test in sanitizer_nolibc_test.cpp).
181    get_target_flags_for_arch(${arch} TARGET_FLAGS)
182    clang_compile(sanitizer_nolibc_test_main.${arch}.o
183                  sanitizer_nolibc_test_main.cpp
184                  CFLAGS ${SANITIZER_TEST_CFLAGS_COMMON} ${TARGET_FLAGS}
185                  DEPS ${SANITIZER_TEST_COMPILE_DEPS})
186    add_compiler_rt_test(SanitizerUnitTests "Sanitizer-${arch}-Test-Nolibc" ${arch}
187                         OBJECTS sanitizer_nolibc_test_main.${arch}.o
188                                 -Wl,-whole-archive
189                                 libRTSanitizerCommon.test.nolibc.${arch}.a
190                                 -Wl,-no-whole-archive
191                         DEPS sanitizer_nolibc_test_main.${arch}.o
192                              RTSanitizerCommon.test.nolibc.${arch}
193                         LINK_FLAGS -static -nostdlib ${TARGET_FLAGS})
194  endif()
195endmacro()
196
197if(COMPILER_RT_CAN_EXECUTE_TESTS AND NOT ANDROID)
198  # We use just-built clang to build sanitizer_common unittests, so we must
199  # be sure that produced binaries would work.
200  if(APPLE)
201    add_sanitizer_common_lib("RTSanitizerCommon.test.osx"
202                             $<TARGET_OBJECTS:RTSanitizerCommon.osx>
203                             $<TARGET_OBJECTS:RTSanitizerCommonLibc.osx>
204                             $<TARGET_OBJECTS:RTSanitizerCommonSymbolizer.osx>)
205  else()
206    if(CAN_TARGET_x86_64)
207      add_sanitizer_common_lib("RTSanitizerCommon.test.nolibc.x86_64"
208                               $<TARGET_OBJECTS:RTSanitizerCommon.x86_64>
209                               $<TARGET_OBJECTS:RTSanitizerCommonNoLibc.x86_64>)
210    endif()
211    foreach(arch ${SANITIZER_UNITTEST_SUPPORTED_ARCH})
212      add_sanitizer_common_lib("RTSanitizerCommon.test.${arch}"
213                               $<TARGET_OBJECTS:RTSanitizerCommon.${arch}>
214                               $<TARGET_OBJECTS:RTSanitizerCommonLibc.${arch}>
215                               $<TARGET_OBJECTS:RTSanitizerCommonSymbolizer.${arch}>)
216    endforeach()
217  endif()
218  foreach(arch ${SANITIZER_UNITTEST_SUPPORTED_ARCH})
219    add_sanitizer_tests_for_arch(${arch})
220  endforeach()
221endif()
222
223if(ANDROID)
224  foreach(arch ${SANITIZER_COMMON_SUPPORTED_ARCH})
225    add_executable(SanitizerTest
226      ${SANITIZER_UNITTESTS}
227      ${COMPILER_RT_GTEST_SOURCE}
228      ${COMPILER_RT_GMOCK_SOURCE}
229      $<TARGET_OBJECTS:RTSanitizerCommon.${arch}>
230      $<TARGET_OBJECTS:RTSanitizerCommonLibc.${arch}>
231      $<TARGET_OBJECTS:RTSanitizerCommonSymbolizer.${arch}>)
232    set_target_compile_flags(SanitizerTest ${SANITIZER_TEST_CFLAGS_COMMON})
233    # Setup correct output directory and link flags.
234    set_target_properties(SanitizerTest PROPERTIES
235      RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
236    set_target_link_flags(SanitizerTest ${SANITIZER_TEST_LINK_FLAGS_COMMON})
237    target_link_libraries(SanitizerTest ${SANITIZER_TEST_LINK_LIBS})
238    # Add unit test to test suite.
239    add_dependencies(SanitizerUnitTests SanitizerTest)
240  endforeach()
241endif()
242