xref: /llvm-project/compiler-rt/lib/asan/tests/CMakeLists.txt (revision a1328c077c9bae5c3b3cb952fe817c4881569cbc)
1# Testing rules for AddressSanitizer.
2#
3# These are broken into two buckets. One set of tests directly interacts with
4# the runtime library and checks its functionality. These are the
5# no-instrumentation tests.
6#
7# Another group of tests relies upon the ability to compile the test with
8# address sanitizer instrumentation pass. These tests form "integration" tests
9# and have some elements of version skew -- they test the *host* compiler's
10# instrumentation against the just-built runtime library.
11
12include(CheckCXXCompilerFlag)
13include(CompilerRTCompile)
14
15include_directories(..)
16include_directories(../..)
17
18set(ASAN_UNITTEST_HEADERS
19  asan_mac_test.h
20  asan_test_config.h
21  asan_test_utils.h)
22
23set(ASAN_UNITTEST_COMMON_CFLAGS
24  ${COMPILER_RT_UNITTEST_CFLAGS}
25  ${COMPILER_RT_GTEST_CFLAGS}
26  ${SANITIZER_TEST_CXX_CFLAGS}
27  -I${COMPILER_RT_SOURCE_DIR}/include
28  -I${COMPILER_RT_SOURCE_DIR}/lib
29  -I${COMPILER_RT_SOURCE_DIR}/lib/asan
30  -I${COMPILER_RT_SOURCE_DIR}/lib/sanitizer_common/tests
31  -DSANITIZER_COMMON_NO_REDEFINE_BUILTINS
32  -fno-rtti
33  -O2
34  -Wno-format
35  -Werror=sign-compare)
36append_list_if(COMPILER_RT_HAS_WVARIADIC_MACROS_FLAG -Wno-variadic-macros ASAN_UNITTEST_COMMON_CFLAGS)
37
38# This will ensure the target linker is used
39# during cross compilation
40set(ASAN_UNITTEST_COMMON_LINK_FLAGS
41  ${COMPILER_RT_UNITTEST_LINK_FLAGS}
42  ${COMPILER_RT_UNWINDER_LINK_LIBS}
43  ${SANITIZER_TEST_CXX_LIBRARIES})
44
45# -gline-tables-only must be enough for ASan, so use it if possible.
46if(COMPILER_RT_TEST_COMPILER_ID MATCHES "Clang")
47  list(APPEND ASAN_UNITTEST_COMMON_CFLAGS -gline-tables-only)
48else()
49  list(APPEND ASAN_UNITTEST_COMMON_CFLAGS -g)
50endif()
51if(MSVC)
52  list(APPEND ASAN_UNITTEST_COMMON_CFLAGS -gcodeview)
53endif()
54list(APPEND ASAN_UNITTEST_COMMON_LINK_FLAGS -g)
55
56# Use -D instead of definitions to please custom compile command.
57list(APPEND ASAN_UNITTEST_COMMON_CFLAGS
58  -DASAN_HAS_IGNORELIST=1
59  -DASAN_HAS_EXCEPTIONS=1
60  -DASAN_UAR=0
61  )
62
63if(APPLE)
64  list(APPEND ASAN_UNITTEST_COMMON_CFLAGS ${DARWIN_osx_CFLAGS})
65  list(APPEND ASAN_UNITTEST_COMMON_LINK_FLAGS ${DARWIN_osx_LINK_FLAGS})
66
67  add_weak_symbols("asan" WEAK_SYMBOL_LINK_FLAGS)
68  add_weak_symbols("ubsan" WEAK_SYMBOL_LINK_FLAGS)
69  add_weak_symbols("sanitizer_common" WEAK_SYMBOL_LINK_FLAGS)
70  list(APPEND ASAN_UNITTEST_COMMON_LINK_FLAGS ${WEAK_SYMBOL_LINK_FLAGS})
71endif()
72
73set(ASAN_IGNORELIST_FILE "${CMAKE_CURRENT_SOURCE_DIR}/asan_test.ignore")
74set(ASAN_UNITTEST_INSTRUMENTED_CFLAGS
75  ${ASAN_UNITTEST_COMMON_CFLAGS}
76  -fsanitize=address
77  "-fsanitize-ignorelist=${ASAN_IGNORELIST_FILE}"
78)
79if(NOT MSVC)
80  list(APPEND ASAN_UNITTEST_COMMON_LINK_FLAGS --driver-mode=g++)
81endif()
82
83# x86_64 FreeBSD 9.2 additionally requires libc++ to build the tests.
84if(CMAKE_SYSTEM MATCHES "FreeBSD-9.2-RELEASE")
85  list(APPEND ASAN_UNITTEST_COMMON_LINK_FLAGS "-lc++")
86endif()
87
88# Unit tests on Mac depend on Foundation.
89if(APPLE)
90  list(APPEND ASAN_UNITTEST_COMMON_LINK_FLAGS -framework Foundation)
91endif()
92if(ANDROID)
93  list(APPEND ASAN_UNITTEST_COMMON_LINK_FLAGS -pie)
94endif()
95
96set(ASAN_UNITTEST_INSTRUMENTED_LINK_FLAGS
97  ${ASAN_UNITTEST_COMMON_LINK_FLAGS})
98list(APPEND ASAN_UNITTEST_INSTRUMENTED_LINK_FLAGS -fsanitize=address)
99
100set(ASAN_DYNAMIC_UNITTEST_INSTRUMENTED_LINK_FLAGS
101  ${ASAN_UNITTEST_INSTRUMENTED_LINK_FLAGS}
102  -shared-libasan)
103
104set(ASAN_UNITTEST_INSTRUMENTED_LIBS)
105
106set(ASAN_UNITTEST_NOINST_LINK_FLAGS ${ASAN_UNITTEST_COMMON_LINK_FLAGS})
107append_list_if(MSVC -Wl,-nodefaultlib:msvcrt ASAN_UNITTEST_NOINST_LINK_FLAGS)
108if(NOT APPLE)
109  append_list_if(COMPILER_RT_HAS_LIBM -lm ASAN_UNITTEST_NOINST_LINK_FLAGS)
110  append_list_if(COMPILER_RT_HAS_LIBDL -ldl ASAN_UNITTEST_NOINST_LINK_FLAGS)
111  append_list_if(COMPILER_RT_HAS_LIBRT -lrt ASAN_UNITTEST_NOINST_LINK_FLAGS)
112  append_list_if(COMPILER_RT_HAS_LIBPTHREAD -pthread ASAN_UNITTEST_NOINST_LINK_FLAGS)
113  append_list_if(COMPILER_RT_HAS_LIBPTHREAD -pthread ASAN_DYNAMIC_UNITTEST_INSTRUMENTED_LINK_FLAGS)
114endif()
115
116# TODO(eugenis): move all -l flags above to _LIBS?
117set(ASAN_UNITTEST_NOINST_LIBS)
118append_list_if(COMPILER_RT_HAS_LIBLOG log ASAN_UNITTEST_NOINST_LIBS)
119
120# Main AddressSanitizer unit tests.
121add_custom_target(AsanUnitTests)
122set_target_properties(AsanUnitTests PROPERTIES FOLDER "Compiler-RT/Tests")
123
124# AddressSanitizer unit tests with dynamic runtime (on platforms where it's
125# not the default).
126add_custom_target(AsanDynamicUnitTests)
127set_target_properties(AsanDynamicUnitTests PROPERTIES FOLDER "Compiler-RT/Tests")
128# ASan benchmarks (not actively used now).
129add_custom_target(AsanBenchmarks)
130set_target_properties(AsanBenchmarks PROPERTIES FOLDER "Compiler-RT/Tests")
131
132set(ASAN_NOINST_TEST_SOURCES
133  ${COMPILER_RT_GTEST_SOURCE}
134  asan_fake_stack_test.cpp
135  asan_noinst_test.cpp
136  asan_test_main.cpp
137  )
138
139set(ASAN_INST_TEST_SOURCES
140  ${COMPILER_RT_GTEST_SOURCE}
141  asan_globals_test.cpp
142  asan_interface_test.cpp
143  asan_internal_interface_test.cpp
144  asan_test.cpp
145  asan_oob_test.cpp
146  asan_mem_test.cpp
147  asan_str_test.cpp
148  asan_test_main.cpp
149  )
150if(APPLE)
151  list(APPEND ASAN_INST_TEST_SOURCES
152    asan_mac_test.cpp
153    asan_mac_test_helpers.mm
154    )
155endif()
156
157set(ASAN_BENCHMARKS_SOURCES
158  ${COMPILER_RT_GTEST_SOURCE}
159  asan_benchmarks_test.cpp
160  )
161
162function(add_asan_tests arch test_runtime)
163  cmake_parse_arguments(TEST "" "KIND" "CFLAGS" ${ARGN})
164
165  # The Lit files are configured once per architecture and static/dynamic
166  # selection. Each configuration expects the test binaries in a corresponding
167  # subdirectory. Generate subdirectory names based on the architecture name.
168  string(TOUPPER ${arch} ARCH_UPPER_CASE)
169  set(CONFIG_NAME ${ARCH_UPPER_CASE}${OS_NAME}Config)
170  set(CONFIG_NAME_DYNAMIC ${ARCH_UPPER_CASE}${OS_NAME}DynamicConfig)
171
172  # Closure to keep the values.
173  function(generate_asan_tests test_objects test_suite testname)
174    generate_compiler_rt_tests(${test_objects} ${test_suite} ${testname} ${arch}
175      COMPILE_DEPS ${ASAN_UNITTEST_HEADERS} ${ASAN_IGNORELIST_FILE}
176      DEPS asan
177      KIND ${TEST_KIND}
178      ${ARGN}
179      )
180    set("${test_objects}" "${${test_objects}}" PARENT_SCOPE)
181  endfunction()
182
183  set(TARGET_LINK_FLAGS)
184  get_target_link_flags_for_arch(${arch} TARGET_LINK_FLAGS)
185
186  set(ASAN_INST_TEST_OBJECTS)
187  generate_asan_tests(ASAN_INST_TEST_OBJECTS AsanUnitTests
188    "Asan-${arch}${TEST_KIND}-Test"
189    SUBDIR "${CONFIG_NAME}"
190    LINK_FLAGS ${ASAN_UNITTEST_INSTRUMENTED_LINK_FLAGS} ${TARGET_LINK_FLAGS}
191    SOURCES ${ASAN_INST_TEST_SOURCES}
192    CFLAGS ${ASAN_UNITTEST_INSTRUMENTED_CFLAGS} ${TEST_CFLAGS})
193
194  if(COMPILER_RT_ASAN_HAS_STATIC_RUNTIME)
195    set(dynamic_test_name "Asan-${arch}${TEST_KIND}-Dynamic-Test")
196    if(MSVC)
197
198      # With the MSVC CRT, the choice between static and dynamic CRT is made at
199      # compile time with a macro. Simulate the effect of passing /MD to clang-cl.
200      set(ASAN_DYNAMIC_TEST_OBJECTS)
201      generate_asan_tests(ASAN_DYNAMIC_TEST_OBJECTS
202        AsanDynamicUnitTests "${dynamic_test_name}"
203        SUBDIR "${CONFIG_NAME_DYNAMIC}"
204        CFLAGS ${ASAN_UNITTEST_INSTRUMENTED_CFLAGS} -D_MT -D_DLL
205        SOURCES ${ASAN_INST_TEST_SOURCES}
206        LINK_FLAGS ${ASAN_DYNAMIC_UNITTEST_INSTRUMENTED_LINK_FLAGS}
207          -D_MT -D_DLL -Wl,-nodefaultlib:libcmt,-defaultlib:msvcrt,-defaultlib:oldnames
208        )
209    else()
210      set(DYNAMIC_LINK_FLAGS)
211      get_dynamic_link_flags_for_arch(${arch} DYNAMIC_LINK_FLAGS)
212
213      # Otherwise, reuse ASAN_INST_TEST_OBJECTS.
214      add_compiler_rt_test(AsanDynamicUnitTests "${dynamic_test_name}" "${arch}"
215        SUBDIR "${CONFIG_NAME_DYNAMIC}"
216        OBJECTS ${ASAN_INST_TEST_OBJECTS}
217        DEPS asan ${ASAN_INST_TEST_OBJECTS}
218        LINK_FLAGS ${ASAN_DYNAMIC_UNITTEST_INSTRUMENTED_LINK_FLAGS} ${TARGET_LINK_FLAGS} ${DYNAMIC_LINK_FLAGS}
219        )
220    endif()
221  endif()
222
223  # Uninstrumented tests.
224  set(ASAN_NOINST_TEST_OBJECTS)
225  generate_asan_tests(ASAN_NOINST_TEST_OBJECTS
226    AsanUnitTests "Asan-${arch}${TEST_KIND}-Noinst-Test"
227    SUBDIR "${CONFIG_NAME}"
228    CFLAGS ${ASAN_UNITTEST_COMMON_CFLAGS}
229    LINK_FLAGS ${ASAN_UNITTEST_NOINST_LINK_FLAGS} ${TARGET_LINK_FLAGS}
230    SOURCES ${ASAN_NOINST_TEST_SOURCES}
231    RUNTIME ${test_runtime})
232
233  set(ASAN_BENCHMARK_OBJECTS)
234  generate_asan_tests(ASAN_BENCHMARK_OBJECTS
235    AsanBenchmarks "Asan-${arch}${TEST_KIND}-Benchmark"
236    SUBDIR "${CONFIG_NAME}"
237    CFLAGS ${ASAN_UNITTEST_INSTRUMENTED_CFLAGS}
238    SOURCES ${ASAN_BENCHMARKS_SOURCES}
239    LINK_FLAGS ${ASAN_UNITTEST_INSTRUMENTED_LINK_FLAGS} ${TARGET_LINK_FLAGS})
240endfunction()
241
242if(COMPILER_RT_CAN_EXECUTE_TESTS AND NOT ANDROID)
243  set(ASAN_TEST_ARCH ${ASAN_SUPPORTED_ARCH})
244  if(APPLE)
245    darwin_filter_host_archs(ASAN_SUPPORTED_ARCH ASAN_TEST_ARCH)
246  endif()
247  list(REMOVE_ITEM ASAN_TEST_ARCH sparcv9)
248  if(OS_NAME MATCHES "SunOS")
249    list(REMOVE_ITEM ASAN_TEST_ARCH x86_64)
250  endif()
251
252  foreach(arch ${ASAN_TEST_ARCH})
253
254    # Add static ASan runtime that will be linked with uninstrumented tests.
255    set(ASAN_TEST_RUNTIME RTAsanTest.${arch})
256    if(APPLE)
257      set(ASAN_TEST_RUNTIME_OBJECTS
258        $<TARGET_OBJECTS:RTAsan_dynamic.osx>
259        $<TARGET_OBJECTS:RTInterception.osx>
260        $<TARGET_OBJECTS:RTSanitizerCommon.osx>
261        $<TARGET_OBJECTS:RTSanitizerCommonLibc.osx>
262        $<TARGET_OBJECTS:RTSanitizerCommonCoverage.osx>
263        $<TARGET_OBJECTS:RTSanitizerCommonSymbolizer.osx>
264        $<TARGET_OBJECTS:RTLSanCommon.osx>
265        $<TARGET_OBJECTS:RTUbsan.osx>)
266    else()
267      set(ASAN_TEST_RUNTIME_OBJECTS
268        $<TARGET_OBJECTS:RTAsan.${arch}>
269        $<TARGET_OBJECTS:RTAsan_cxx.${arch}>
270        $<TARGET_OBJECTS:RTAsan_static.${arch}>
271        $<TARGET_OBJECTS:RTInterception.${arch}>
272        $<TARGET_OBJECTS:RTSanitizerCommon.${arch}>
273        $<TARGET_OBJECTS:RTSanitizerCommonLibc.${arch}>
274        $<TARGET_OBJECTS:RTSanitizerCommonCoverage.${arch}>
275        $<TARGET_OBJECTS:RTSanitizerCommonSymbolizer.${arch}>
276        $<TARGET_OBJECTS:RTSanitizerCommonSymbolizerInternal.${arch}>
277        $<TARGET_OBJECTS:RTLSanCommon.${arch}>
278        $<TARGET_OBJECTS:RTUbsan.${arch}>)
279    endif()
280    add_library(${ASAN_TEST_RUNTIME} STATIC ${ASAN_TEST_RUNTIME_OBJECTS})
281    set_target_properties(${ASAN_TEST_RUNTIME} PROPERTIES
282      ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
283      FOLDER "Compiler-RT/Tests/Runtime")
284
285    add_asan_tests(${arch} ${ASAN_TEST_RUNTIME} KIND "-inline")
286    add_asan_tests(${arch} ${ASAN_TEST_RUNTIME} KIND "-calls"
287      CFLAGS -mllvm -asan-instrumentation-with-call-threshold=0)
288  endforeach()
289endif()
290
291if(ANDROID)
292  foreach(arch ${ASAN_SUPPORTED_ARCH})
293    # Test w/o ASan instrumentation. Link it with ASan statically.
294    add_executable(AsanNoinstTest # FIXME: .arch?
295      $<TARGET_OBJECTS:RTAsan.${arch}>
296      $<TARGET_OBJECTS:RTAsan_static.${arch}>
297      $<TARGET_OBJECTS:RTInterception.${arch}>
298      $<TARGET_OBJECTS:RTSanitizerCommon.${arch}>
299      $<TARGET_OBJECTS:RTSanitizerCommonLibc.${arch}>
300      $<TARGET_OBJECTS:RTSanitizerCommonCoverage.${arch}>
301      $<TARGET_OBJECTS:RTSanitizerCommonSymbolizer.${arch}>
302      $<TARGET_OBJECTS:RTSanitizerCommonSymbolizerInternal.${arch}>
303      $<TARGET_OBJECTS:RTLSanCommon.${arch}>
304      $<TARGET_OBJECTS:RTUbsan.${arch}>
305      ${COMPILER_RT_GTEST_SOURCE}
306      ${ASAN_NOINST_TEST_SOURCES})
307    set_target_compile_flags(AsanNoinstTest ${ASAN_UNITTEST_COMMON_CFLAGS})
308    set_target_link_flags(AsanNoinstTest ${ASAN_UNITTEST_NOINST_LINK_FLAGS})
309    target_link_libraries(AsanNoinstTest ${ASAN_UNITTEST_NOINST_LIBS})
310
311    # Test with ASan instrumentation. Link with ASan dynamic runtime.
312    add_executable(AsanTest
313      ${COMPILER_RT_GTEST_SOURCE}
314      ${ASAN_INST_TEST_SOURCES})
315    set_target_compile_flags(AsanTest ${ASAN_UNITTEST_INSTRUMENTED_CFLAGS})
316    set_target_link_flags(AsanTest ${ASAN_UNITTEST_INSTRUMENTED_LINK_FLAGS})
317    target_link_libraries(AsanTest ${ASAN_UNITTEST_INSTRUMENTED_LIBS})
318
319    # Setup correct output directory and link flags.
320    set_target_properties(AsanNoinstTest AsanTest PROPERTIES
321      RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
322    # Add unit tests to the test suite.
323    add_dependencies(AsanUnitTests AsanNoinstTest AsanTest)
324  endforeach()
325endif()
326