1 # Testing rules for AddressSanitizer.
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.
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.
12 include(CheckCXXCompilerFlag)
13 include(CompilerRTCompile)
15 include_directories(..)
16 include_directories(../..)
18 set(ASAN_UNITTEST_HEADERS
23 set(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
34 append_if(COMPILER_RT_HAS_WNO_VARIADIC_MACROS_FLAG -Wno-variadic-macros ASAN_UNITTEST_COMMON_CFLAGS)
36 # -gline-tables-only must be enough for ASan, so use it if possible.
37 if(COMPILER_RT_TEST_COMPILER_ID MATCHES "Clang")
38 list(APPEND ASAN_UNITTEST_COMMON_CFLAGS -gline-tables-only)
40 list(APPEND ASAN_UNITTEST_COMMON_CFLAGS -g)
43 # Use -D instead of definitions to please custom compile command.
44 list(APPEND ASAN_UNITTEST_COMMON_CFLAGS
45 -DASAN_HAS_BLACKLIST=1
46 -DASAN_HAS_EXCEPTIONS=1
49 set(ASAN_BLACKLIST_FILE "${CMAKE_CURRENT_SOURCE_DIR}/asan_test.ignore")
50 set(ASAN_UNITTEST_INSTRUMENTED_CFLAGS
51 ${ASAN_UNITTEST_COMMON_CFLAGS}
53 "-fsanitize-blacklist=${ASAN_BLACKLIST_FILE}"
54 -mllvm -asan-instrument-assembly
58 list(APPEND ASAN_UNITTEST_COMMON_LINKFLAGS --driver-mode=g++)
61 # x86_64 FreeBSD 9.2 additionally requires libc++ to build the tests.
62 if(CMAKE_SYSTEM MATCHES "FreeBSD-9.2-RELEASE")
63 list(APPEND ASAN_UNITTEST_COMMON_LINKFLAGS "-lc++")
66 # Unit tests on Mac depend on Foundation.
68 list(APPEND ASAN_UNITTEST_COMMON_LINKFLAGS -framework Foundation)
71 list(APPEND ASAN_UNITTEST_COMMON_LINKFLAGS -pie)
74 set(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.
79 list(APPEND ASAN_UNITTEST_INSTRUMENTED_LINKFLAGS -fsanitize=address)
82 set(ASAN_DYNAMIC_UNITTEST_INSTRUMENTED_LINKFLAGS
83 ${ASAN_UNITTEST_INSTRUMENTED_LINKFLAGS}
86 set(ASAN_UNITTEST_NOINST_LINKFLAGS ${ASAN_UNITTEST_COMMON_LINKFLAGS})
87 append_if(COMPILER_RT_HAS_LIBM -lm ASAN_UNITTEST_NOINST_LINKFLAGS)
88 append_if(COMPILER_RT_HAS_LIBDL -ldl ASAN_UNITTEST_NOINST_LINKFLAGS)
89 append_if(COMPILER_RT_HAS_LIBPTHREAD -lpthread ASAN_UNITTEST_NOINST_LINKFLAGS)
90 append_if(COMPILER_RT_HAS_LIBPTHREAD -lpthread
91 ASAN_DYNAMIC_UNITTEST_INSTRUMENTED_LINKFLAGS)
93 # Compile source for the given architecture, using compiler
94 # options in ${ARGN}, and add it to the object list.
95 macro(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)
103 clang_compile(${output_obj} ${source}
104 CFLAGS ${ARGN} ${TARGET_CFLAGS}
105 DEPS ${COMPILE_DEPS})
106 list(APPEND ${obj_list} ${output_obj})
109 # Link ASan unit test for a given architecture from a set
110 # of objects in with given linker flags.
111 macro(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)
118 if(TEST_WITH_TEST_RUNTIME)
119 list(APPEND TEST_DEPS ${ASAN_TEST_RUNTIME})
121 list(APPEND TEST_OBJECTS lib${ASAN_TEST_RUNTIME}.a)
123 list(APPEND TEST_OBJECTS ${ASAN_TEST_RUNTIME}.lib)
126 add_compiler_rt_test(${test_suite} ${test_name}
127 OBJECTS ${TEST_OBJECTS}
129 LINK_FLAGS ${TEST_LINKFLAGS}
130 ${TARGET_LINK_FLAGS})
133 # Main AddressSanitizer unit tests.
134 add_custom_target(AsanUnitTests)
135 set_target_properties(AsanUnitTests PROPERTIES FOLDER "ASan unit tests")
136 # ASan benchmarks (not actively used now).
137 add_custom_target(AsanBenchmarks)
138 set_target_properties(AsanBenchmarks PROPERTIES FOLDER "Asan benchmarks")
140 set(ASAN_NOINST_TEST_SOURCES
141 ${COMPILER_RT_GTEST_SOURCE}
142 asan_fake_stack_test.cc
146 set(ASAN_INST_TEST_SOURCES
147 ${COMPILER_RT_GTEST_SOURCE}
150 asan_interface_test.cc
157 list(APPEND ASAN_INST_TEST_SOURCES asan_mac_test.cc)
160 set(ASAN_BENCHMARKS_SOURCES
161 ${COMPILER_RT_GTEST_SOURCE}
162 asan_benchmarks_test.cc)
164 # Adds ASan unit tests and benchmarks for architecture.
165 macro(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})
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})
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})
186 # Add static ASan runtime that will be linked with uninstrumented tests.
187 set(ASAN_TEST_RUNTIME RTAsanTest.${arch}${kind})
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>)
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}>)
202 list(APPEND ASAN_TEST_RUNTIME_OBJECTS
203 $<TARGET_OBJECTS:RTLSanCommon.${arch}>)
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})
215 add_asan_test(AsanUnitTests "Asan-${arch}${kind}-Noinst-Test" ${arch} ${kind}
216 OBJECTS ${ASAN_NOINST_TEST_OBJECTS}
217 LINKFLAGS ${ASAN_UNITTEST_NOINST_LINKFLAGS}
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})
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})
236 if(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)
245 # We assume that unit tests on Android are built in a build
246 # tree with fresh Clang as a host compiler.
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)
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)
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)