CMakeLists.txt revision 5d71de26cedae3dafc17449fe0182045c0bd20e8
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_TEST_CFLAGS}
25  ${COMPILER_RT_GTEST_CFLAGS}
26  -I${COMPILER_RT_SOURCE_DIR}/include
27  -I${COMPILER_RT_SOURCE_DIR}/lib
28  -I${COMPILER_RT_SOURCE_DIR}/lib/asan
29  -I${COMPILER_RT_SOURCE_DIR}/lib/sanitizer_common/tests
30  -fno-rtti
31  -O2
32  -Wno-format
33  -Werror=sign-compare)
34append_if(COMPILER_RT_HAS_WNO_VARIADIC_MACROS_FLAG -Wno-variadic-macros ASAN_UNITTEST_COMMON_CFLAGS)
35
36# -gline-tables-only must be enough for ASan, so use it if possible.
37if(COMPILER_RT_TEST_COMPILER_ID MATCHES "Clang")
38  list(APPEND ASAN_UNITTEST_COMMON_CFLAGS -gline-tables-only)
39else()
40  list(APPEND ASAN_UNITTEST_COMMON_CFLAGS -g)
41endif()
42
43# Use -D instead of definitions to please custom compile command.
44list(APPEND ASAN_UNITTEST_COMMON_CFLAGS
45  -DASAN_HAS_BLACKLIST=1
46  -DASAN_HAS_EXCEPTIONS=1
47  -DASAN_UAR=0)
48
49set(ASAN_BLACKLIST_FILE "${CMAKE_CURRENT_SOURCE_DIR}/asan_test.ignore")
50set(ASAN_UNITTEST_INSTRUMENTED_CFLAGS
51  ${ASAN_UNITTEST_COMMON_CFLAGS}
52  -fsanitize=address
53  "-fsanitize-blacklist=${ASAN_BLACKLIST_FILE}"
54  -mllvm -asan-instrument-assembly
55)
56
57if(NOT MSVC)
58  list(APPEND ASAN_UNITTEST_COMMON_LINKFLAGS --driver-mode=g++)
59endif()
60
61# x86_64 FreeBSD 9.2 additionally requires libc++ to build the tests.
62if(CMAKE_SYSTEM MATCHES "FreeBSD-9.2-RELEASE")
63  list(APPEND ASAN_UNITTEST_COMMON_LINKFLAGS "-lc++")
64endif()
65
66# Unit tests on Mac depend on Foundation.
67if(APPLE)
68  list(APPEND ASAN_UNITTEST_COMMON_LINKFLAGS -framework Foundation)
69endif()
70if(ANDROID)
71  list(APPEND ASAN_UNITTEST_COMMON_LINKFLAGS -pie)
72endif()
73
74set(ASAN_UNITTEST_INSTRUMENTED_LINKFLAGS
75  ${ASAN_UNITTEST_COMMON_LINKFLAGS})
76# On Android, we link with ASan runtime manually. On other platforms we depend
77# on Clang driver behavior, passing -fsanitize=address flag.
78if(NOT ANDROID)
79  list(APPEND ASAN_UNITTEST_INSTRUMENTED_LINKFLAGS -fsanitize=address)
80endif()
81
82set(ASAN_DYNAMIC_UNITTEST_INSTRUMENTED_LINKFLAGS
83  ${ASAN_UNITTEST_INSTRUMENTED_LINKFLAGS}
84  -shared-libasan)
85
86set(ASAN_UNITTEST_NOINST_LINKFLAGS ${ASAN_UNITTEST_COMMON_LINKFLAGS})
87append_if(COMPILER_RT_HAS_LIBM -lm ASAN_UNITTEST_NOINST_LINKFLAGS)
88append_if(COMPILER_RT_HAS_LIBDL -ldl ASAN_UNITTEST_NOINST_LINKFLAGS)
89append_if(COMPILER_RT_HAS_LIBPTHREAD -pthread ASAN_UNITTEST_NOINST_LINKFLAGS)
90append_if(COMPILER_RT_HAS_LIBPTHREAD -pthread
91          ASAN_DYNAMIC_UNITTEST_INSTRUMENTED_LINKFLAGS)
92
93# Compile source for the given architecture, using compiler
94# options in ${ARGN}, and add it to the object list.
95macro(asan_compile obj_list source arch kind)
96  get_filename_component(basename ${source} NAME)
97  set(output_obj "${obj_list}.${basename}.${arch}${kind}.o")
98  get_target_flags_for_arch(${arch} TARGET_CFLAGS)
99  set(COMPILE_DEPS ${ASAN_UNITTEST_HEADERS} ${ASAN_BLACKLIST_FILE})
100  if(NOT COMPILER_RT_STANDALONE_BUILD)
101    list(APPEND COMPILE_DEPS gtest asan)
102  endif()
103  clang_compile(${output_obj} ${source}
104                CFLAGS ${ARGN} ${TARGET_CFLAGS}
105                DEPS ${COMPILE_DEPS})
106  list(APPEND ${obj_list} ${output_obj})
107endmacro()
108
109# Link ASan unit test for a given architecture from a set
110# of objects in with given linker flags.
111macro(add_asan_test test_suite test_name arch kind)
112  parse_arguments(TEST "OBJECTS;LINKFLAGS" "WITH_TEST_RUNTIME" ${ARGN})
113  get_target_flags_for_arch(${arch} TARGET_LINK_FLAGS)
114  set(TEST_DEPS ${TEST_OBJECTS})
115  if(NOT COMPILER_RT_STANDALONE_BUILD)
116    list(APPEND TEST_DEPS asan)
117  endif()
118  if(TEST_WITH_TEST_RUNTIME)
119    list(APPEND TEST_DEPS ${ASAN_TEST_RUNTIME})
120    if(NOT MSVC)
121      list(APPEND TEST_OBJECTS lib${ASAN_TEST_RUNTIME}.a)
122    else()
123      list(APPEND TEST_OBJECTS ${ASAN_TEST_RUNTIME}.lib)
124    endif()
125  endif()
126  add_compiler_rt_test(${test_suite} ${test_name}
127                       OBJECTS ${TEST_OBJECTS}
128                       DEPS ${TEST_DEPS}
129                       LINK_FLAGS ${TEST_LINKFLAGS}
130                                  ${TARGET_LINK_FLAGS})
131endmacro()
132
133# Main AddressSanitizer unit tests.
134add_custom_target(AsanUnitTests)
135set_target_properties(AsanUnitTests PROPERTIES FOLDER "ASan unit tests")
136# ASan benchmarks (not actively used now).
137add_custom_target(AsanBenchmarks)
138set_target_properties(AsanBenchmarks PROPERTIES FOLDER "Asan benchmarks")
139
140set(ASAN_NOINST_TEST_SOURCES
141  ${COMPILER_RT_GTEST_SOURCE}
142  asan_fake_stack_test.cc
143  asan_noinst_test.cc
144  asan_test_main.cc)
145
146set(ASAN_INST_TEST_SOURCES
147  ${COMPILER_RT_GTEST_SOURCE}
148  asan_asm_test.cc
149  asan_globals_test.cc
150  asan_interface_test.cc
151  asan_test.cc
152  asan_oob_test.cc
153  asan_mem_test.cc
154  asan_str_test.cc
155  asan_test_main.cc)
156if(APPLE)
157  list(APPEND ASAN_INST_TEST_SOURCES asan_mac_test.cc)
158endif()
159
160set(ASAN_BENCHMARKS_SOURCES
161  ${COMPILER_RT_GTEST_SOURCE}
162  asan_benchmarks_test.cc)
163
164# Adds ASan unit tests and benchmarks for architecture.
165macro(add_asan_tests_for_arch_and_kind arch kind)
166  # Instrumented tests.
167  set(ASAN_INST_TEST_OBJECTS)
168  foreach(src ${ASAN_INST_TEST_SOURCES})
169    asan_compile(ASAN_INST_TEST_OBJECTS ${src} ${arch} ${kind}
170      ${ASAN_UNITTEST_INSTRUMENTED_CFLAGS} ${ARGN})
171  endforeach()
172  if (APPLE)
173    # Add Mac-specific helper.
174    asan_compile(ASAN_INST_TEST_OBJECTS asan_mac_test_helpers.mm ${arch} ${kind}
175                 ${ASAN_UNITTEST_INSTRUMENTED_CFLAGS} -ObjC ${ARGN})
176  endif()
177  add_asan_test(AsanUnitTests "Asan-${arch}${kind}-Test" ${arch} ${kind}
178                OBJECTS ${ASAN_INST_TEST_OBJECTS}
179                LINKFLAGS ${ASAN_UNITTEST_INSTRUMENTED_LINKFLAGS})
180  if(COMPILER_RT_BUILD_SHARED_ASAN)
181    add_asan_test(AsanUnitTests "Asan-${arch}${kind}-Dynamic-Test" ${arch} ${kind}
182                  OBJECTS ${ASAN_INST_TEST_OBJECTS}
183                  LINKFLAGS ${ASAN_DYNAMIC_UNITTEST_INSTRUMENTED_LINKFLAGS})
184  endif()
185
186  # Add static ASan runtime that will be linked with uninstrumented tests.
187  set(ASAN_TEST_RUNTIME RTAsanTest.${arch}${kind})
188  if(APPLE)
189    set(ASAN_TEST_RUNTIME_OBJECTS
190      $<TARGET_OBJECTS:RTAsan.osx>
191      $<TARGET_OBJECTS:RTInterception.osx>
192      $<TARGET_OBJECTS:RTSanitizerCommon.osx>
193      $<TARGET_OBJECTS:RTLSanCommon.osx>)
194  else()
195    set(ASAN_TEST_RUNTIME_OBJECTS
196      $<TARGET_OBJECTS:RTAsan.${arch}>
197      $<TARGET_OBJECTS:RTAsan_cxx.${arch}>
198      $<TARGET_OBJECTS:RTInterception.${arch}>
199      $<TARGET_OBJECTS:RTSanitizerCommon.${arch}>
200      $<TARGET_OBJECTS:RTSanitizerCommonLibc.${arch}>)
201    if(NOT MSVC)
202      list(APPEND ASAN_TEST_RUNTIME_OBJECTS
203           $<TARGET_OBJECTS:RTLSanCommon.${arch}>)
204    endif()
205  endif()
206  add_library(${ASAN_TEST_RUNTIME} STATIC ${ASAN_TEST_RUNTIME_OBJECTS})
207  set_target_properties(${ASAN_TEST_RUNTIME} PROPERTIES
208    ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
209  # Uninstrumented tests.
210  set(ASAN_NOINST_TEST_OBJECTS)
211  foreach(src ${ASAN_NOINST_TEST_SOURCES})
212    asan_compile(ASAN_NOINST_TEST_OBJECTS ${src} ${arch} ${kind}
213                 ${ASAN_UNITTEST_COMMON_CFLAGS} ${ARGN})
214  endforeach()
215  add_asan_test(AsanUnitTests "Asan-${arch}${kind}-Noinst-Test" ${arch} ${kind}
216                OBJECTS ${ASAN_NOINST_TEST_OBJECTS}
217                LINKFLAGS ${ASAN_UNITTEST_NOINST_LINKFLAGS}
218                WITH_TEST_RUNTIME)
219
220  # Benchmarks.
221  set(ASAN_BENCHMARKS_OBJECTS)
222  foreach(src ${ASAN_BENCHMARKS_SOURCES})
223    asan_compile(ASAN_BENCHMARKS_OBJECTS ${src} ${arch} ${kind}
224                 ${ASAN_UNITTEST_INSTRUMENTED_CFLAGS} ${ARGN})
225  endforeach()
226  add_asan_test(AsanBenchmarks "Asan-${arch}${kind}-Benchmark" ${arch} ${kind}
227                OBJECTS ${ASAN_BENCHMARKS_OBJECTS}
228                LINKFLAGS ${ASAN_UNITTEST_INSTRUMENTED_LINKFLAGS})
229  if(COMPILER_RT_BUILD_SHARED_ASAN)
230    add_asan_test(AsanBenchmarks "Asan-${arch}${kind}-Dynamic-Benchmark" ${arch} ${kind}
231                  OBJECTS ${ASAN_BENCHMARKS_OBJECTS}
232                  LINKFLAGS ${ASAN_DYNAMIC_UNITTEST_INSTRUMENTED_LINKFLAGS})
233  endif()
234endmacro()
235
236if(COMPILER_RT_CAN_EXECUTE_TESTS)
237  foreach(arch ${ASAN_SUPPORTED_ARCH})
238    add_asan_tests_for_arch_and_kind(${arch} "-inline")
239    add_asan_tests_for_arch_and_kind(${arch} "-with-calls"
240      -mllvm -asan-instrumentation-with-call-threshold=0)
241  endforeach()
242endif()
243
244if(ANDROID)
245  # We assume that unit tests on Android are built in a build
246  # tree with fresh Clang as a host compiler.
247  
248  # Test w/o ASan instrumentation. Link it with ASan statically.
249  add_executable(AsanNoinstTest
250    $<TARGET_OBJECTS:RTAsan.arm.android>
251    $<TARGET_OBJECTS:RTInterception.arm.android>
252    $<TARGET_OBJECTS:RTSanitizerCommon.arm.android>
253    ${COMPILER_RT_GTEST_SOURCE}
254    ${ASAN_NOINST_TEST_SOURCES})
255  set_target_compile_flags(AsanNoinstTest ${ASAN_UNITTEST_COMMON_CFLAGS})
256  set_target_link_flags(AsanNoinstTest ${ASAN_UNITTEST_NOINST_LINKFLAGS})
257  target_link_libraries(AsanNoinstTest log)
258
259  # Test with ASan instrumentation. Link with ASan dynamic runtime.
260  add_executable(AsanTest
261    ${COMPILER_RT_GTEST_SOURCE}
262    ${ASAN_INST_TEST_SOURCES})
263  set_target_compile_flags(AsanTest ${ASAN_UNITTEST_INSTRUMENTED_CFLAGS})
264  set_target_link_flags(AsanTest ${ASAN_UNITTEST_INSTRUMENTED_LINKFLAGS})
265  target_link_libraries(AsanTest clang_rt.asan-arm-android)
266
267  # Setup correct output directory and link flags.
268  set_target_properties(AsanNoinstTest AsanTest PROPERTIES
269    RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
270  # Add unit test to test suite.
271  add_dependencies(AsanUnitTests AsanNoinstTest AsanTest)
272endif()
273