CMakeLists.txt revision bdd9545da55933797edf58c6049d894ed0efb465
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
18# Use zero-based shadow on Android.
19if(ANDROID)
20  set(ASAN_TESTS_USE_ZERO_BASE_SHADOW TRUE)
21else()
22  set(ASAN_TESTS_USE_ZERO_BASE_SHADOW FALSE)
23endif()
24
25set(ASAN_UNITTEST_HEADERS
26  asan_mac_test.h
27  asan_test_config.h
28  asan_test_utils.h)
29
30set(ASAN_UNITTEST_COMMON_CFLAGS
31  ${COMPILER_RT_GTEST_INCLUDE_CFLAGS}
32  -I${COMPILER_RT_SOURCE_DIR}/include
33  -I${COMPILER_RT_SOURCE_DIR}/lib
34  -I${COMPILER_RT_SOURCE_DIR}/lib/asan
35  -I${COMPILER_RT_SOURCE_DIR}/lib/sanitizer_common/tests
36  -Wall
37  -Wno-format
38  -Werror
39  -g
40  -O2
41)
42
43if(ASAN_TESTS_USE_ZERO_BASE_SHADOW)
44  list(APPEND ASAN_UNITTEST_COMMON_CFLAGS -fPIE)
45endif()
46if(SUPPORTS_NO_VARIADIC_MACROS_FLAG)
47  list(APPEND ASAN_UNITTEST_COMMON_CFLAGS -Wno-variadic-macros)
48endif()
49
50# Use -D instead of definitions to please custom compile command.
51list(APPEND ASAN_UNITTEST_COMMON_CFLAGS
52  -DASAN_HAS_BLACKLIST=1
53  -DASAN_HAS_EXCEPTIONS=1
54  -DASAN_UAR=0)
55if(ANDROID)
56  list(APPEND ASAN_UNITTEST_COMMON_CFLAGS
57    -DASAN_FLEXIBLE_MAPPING_AND_OFFSET=0
58    -DASAN_NEEDS_SEGV=0)
59else()
60  list(APPEND ASAN_UNITTEST_COMMON_CFLAGS
61    -DASAN_FLEXIBLE_MAPPING_AND_OFFSET=1
62    -DASAN_NEEDS_SEGV=1)
63endif()
64
65set(ASAN_LINK_FLAGS)
66if(ASAN_TESTS_USE_ZERO_BASE_SHADOW)
67  list(APPEND ASAN_LINK_FLAGS -pie)
68endif()
69# On Android, we link with ASan runtime manually. On other platforms we depend
70# on Clang driver behavior, passing -fsanitize=address flag.
71if(NOT ANDROID)
72  list(APPEND ASAN_LINK_FLAGS -fsanitize=address)
73endif()
74# Unit tests on Mac depend on Foundation.
75if(APPLE)
76  list(APPEND ASAN_LINK_FLAGS -framework Foundation)
77endif()
78# Unit tests require libstdc++.
79list(APPEND ASAN_LINK_FLAGS -lstdc++)
80
81set(ASAN_BLACKLIST_FILE "${CMAKE_CURRENT_SOURCE_DIR}/asan_test.ignore")
82
83set(ASAN_UNITTEST_INSTRUMENTED_CFLAGS
84  ${ASAN_UNITTEST_COMMON_CFLAGS}
85  -fsanitize=address
86  "-fsanitize-blacklist=${ASAN_BLACKLIST_FILE}"
87  -mllvm -asan-stack=1
88  -mllvm -asan-globals=1
89  -mllvm -asan-mapping-scale=0        # default will be used
90  -mllvm -asan-mapping-offset-log=-1  # default will be used
91  -mllvm -asan-use-after-return=0
92)
93if(ASAN_TESTS_USE_ZERO_BASE_SHADOW)
94  list(APPEND ASAN_UNITTEST_INSTRUMENTED_CFLAGS
95    -fsanitize-address-zero-base-shadow)
96endif()
97
98# Compile source for the given architecture, using compiler
99# options in ${ARGN}, and add it to the object list.
100macro(asan_compile obj_list source arch)
101  get_filename_component(basename ${source} NAME)
102  set(output_obj "${basename}.${arch}.o")
103  get_target_flags_for_arch(${arch} TARGET_CFLAGS)
104  clang_compile(${output_obj} ${source}
105                CFLAGS ${ARGN} ${TARGET_CFLAGS}
106                DEPS gtest ${ASAN_RUNTIME_LIBRARIES}
107                           ${ASAN_UNITTEST_HEADERS}
108                           ${ASAN_BLACKLIST_FILE})
109  list(APPEND ${obj_list} ${output_obj})
110endmacro()
111
112# Link ASan unit test for a given architecture from a set
113# of objects in ${ARGN}.
114macro(add_asan_test test_suite test_name arch)
115  get_target_flags_for_arch(${arch} TARGET_LINK_FLAGS)
116  add_compiler_rt_test(${test_suite} ${test_name}
117                       OBJECTS ${ARGN}
118                       DEPS ${ASAN_RUNTIME_LIBRARIES} ${ARGN}
119                       LINK_FLAGS ${ASAN_LINK_FLAGS}
120                                  ${TARGET_LINK_FLAGS})
121endmacro()
122
123# Main AddressSanitizer unit tests.
124add_custom_target(AsanUnitTests)
125set_target_properties(AsanUnitTests PROPERTIES FOLDER "ASan unit tests")
126# ASan benchmarks (not actively used now).
127add_custom_target(AsanBenchmarks)
128set_target_properties(AsanBenchmarks PROPERTIES FOLDER "Asan benchmarks")
129
130if (NOT APPLE)
131# Do not build asan_fake_stack_test.cc on OS X, since it requires exposing
132# additional functions from the runtime.
133# See also https://code.google.com/p/address-sanitizer/issues/detail?id=222
134set(ASAN_NOINST_TEST_SOURCES
135  asan_fake_stack_test.cc
136  asan_noinst_test.cc
137  asan_test_main.cc)
138else()
139set(ASAN_NOINST_TEST_SOURCES
140  asan_noinst_test.cc
141  asan_test_main.cc)
142endif()
143
144set(ASAN_INST_TEST_SOURCES
145  asan_globals_test.cc
146  asan_test.cc
147  asan_oob_test.cc
148  asan_mem_test.cc
149  asan_str_test.cc)
150
151# Adds ASan unit tests and benchmarks for architecture.
152macro(add_asan_tests_for_arch arch)
153  # Build gtest instrumented with ASan.
154  set(ASAN_INST_GTEST)
155  asan_compile(ASAN_INST_GTEST ${COMPILER_RT_GTEST_SOURCE} ${arch} 
156                               ${ASAN_UNITTEST_INSTRUMENTED_CFLAGS})
157  # Instrumented tests.
158  set(ASAN_INST_TEST_OBJECTS)
159  foreach(src ${ASAN_INST_TEST_SOURCES})
160    asan_compile(ASAN_INST_TEST_OBJECTS ${src} ${arch}
161                 ${ASAN_UNITTEST_INSTRUMENTED_CFLAGS})
162  endforeach()
163  # Add Mac-specific tests.
164  if (APPLE)
165    asan_compile(ASAN_INST_TEST_OBJECTS asan_mac_test.cc ${arch}
166                 ${ASAN_UNITTEST_INSTRUMENTED_CFLAGS})
167    asan_compile(ASAN_INST_TEST_OBJECTS asan_mac_test_helpers.mm ${arch}
168                 ${ASAN_UNITTEST_INSTRUMENTED_CFLAGS} -ObjC)
169  endif()
170  # Uninstrumented tests.
171  set(ASAN_NOINST_TEST_OBJECTS)
172  foreach(src ${ASAN_NOINST_TEST_SOURCES})
173    asan_compile(ASAN_NOINST_TEST_OBJECTS ${src} ${arch}
174                 ${ASAN_UNITTEST_COMMON_CFLAGS})
175  endforeach()
176  # Link everything together.
177  add_asan_test(AsanUnitTests "Asan-${arch}-Test" ${arch}
178                ${ASAN_NOINST_TEST_OBJECTS}
179                ${ASAN_INST_TEST_OBJECTS} ${ASAN_INST_GTEST})
180
181  # Instrumented benchmarks.
182  set(ASAN_BENCHMARKS_OBJECTS)
183  asan_compile(ASAN_BENCHMARKS_OBJECTS asan_benchmarks_test.cc ${arch}
184               ${ASAN_UNITTEST_INSTRUMENTED_CFLAGS})
185  # Link benchmarks.
186  add_asan_test(AsanBenchmarks "Asan-${arch}-Benchmark" ${arch}
187                ${ASAN_BENCHMARKS_OBJECTS} ${ASAN_INST_GTEST})
188endmacro()
189
190if(COMPILER_RT_CAN_EXECUTE_TESTS)
191  foreach(arch ${ASAN_SUPPORTED_ARCH})
192    add_asan_tests_for_arch(${arch})
193  endforeach()
194endif()
195
196if(ANDROID)
197  # We assume that unit tests on Android are built in a build
198  # tree with fresh Clang as a host compiler.
199  add_library(asan_noinst_test OBJECT ${ASAN_NOINST_TEST_SOURCES})
200  set_target_compile_flags(asan_noinst_test ${ASAN_UNITTEST_COMMON_CFLAGS})
201  add_library(asan_inst_test OBJECT
202              ${ASAN_INST_TEST_SOURCES} ${COMPILER_RT_GTEST_SOURCE})  
203  set_target_compile_flags(asan_inst_test ${ASAN_UNITTEST_INSTRUMENTED_CFLAGS})
204  add_executable(AsanTest
205    $<TARGET_OBJECTS:asan_noinst_test>
206    $<TARGET_OBJECTS:asan_inst_test>
207  )
208  # Setup correct output directory and link flags.
209  set_target_properties(AsanTest PROPERTIES
210    RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
211  set_target_link_flags(AsanTest ${ASAN_LINK_FLAGS})
212  target_link_libraries(AsanTest clang_rt.asan-arm-android)
213  # Add unit test to test suite.
214  add_dependencies(AsanUnitTests AsanTest)
215endif()
216