CMakeLists.txt revision c74b2ccbc0cf40bb401ebf3758e8e964b22acb3a
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_LOW_MEMORY=1
59    -DASAN_NEEDS_SEGV=0)
60else()
61  list(APPEND ASAN_UNITTEST_COMMON_CFLAGS
62    -DASAN_FLEXIBLE_MAPPING_AND_OFFSET=1
63    -DASAN_LOW_MEMORY=0
64    -DASAN_NEEDS_SEGV=1)
65endif()
66
67set(ASAN_LINK_FLAGS)
68if(ASAN_TESTS_USE_ZERO_BASE_SHADOW)
69  list(APPEND ASAN_LINK_FLAGS -pie)
70endif()
71# On Android, we link with ASan runtime manually. On other platforms we depend
72# on Clang driver behavior, passing -fsanitize=address flag.
73if(NOT ANDROID)
74  list(APPEND ASAN_LINK_FLAGS -fsanitize=address)
75endif()
76# Unit tests on Mac depend on Foundation.
77if(APPLE)
78  list(APPEND ASAN_LINK_FLAGS -framework Foundation)
79endif()
80# Unit tests require libstdc++.
81list(APPEND ASAN_LINK_FLAGS -lstdc++)
82
83set(ASAN_BLACKLIST_FILE "${CMAKE_CURRENT_SOURCE_DIR}/asan_test.ignore")
84
85set(ASAN_UNITTEST_INSTRUMENTED_CFLAGS
86  ${ASAN_UNITTEST_COMMON_CFLAGS}
87  -fsanitize=address
88  "-fsanitize-blacklist=${ASAN_BLACKLIST_FILE}"
89  -mllvm -asan-stack=1
90  -mllvm -asan-globals=1
91  -mllvm -asan-mapping-scale=0        # default will be used
92  -mllvm -asan-mapping-offset-log=-1  # default will be used
93  -mllvm -asan-use-after-return=0
94)
95if(ASAN_TESTS_USE_ZERO_BASE_SHADOW)
96  list(APPEND ASAN_UNITTEST_INSTRUMENTED_CFLAGS
97    -fsanitize-address-zero-base-shadow)
98endif()
99
100# Compile source for the given architecture, using compiler
101# options in ${ARGN}, and add it to the object list.
102macro(asan_compile obj_list source arch)
103  get_filename_component(basename ${source} NAME)
104  set(output_obj "${basename}.${arch}.o")
105  get_target_flags_for_arch(${arch} TARGET_CFLAGS)
106  clang_compile(${output_obj} ${source}
107                CFLAGS ${ARGN} ${TARGET_CFLAGS}
108                DEPS gtest ${ASAN_RUNTIME_LIBRARIES}
109                           ${ASAN_UNITTEST_HEADERS}
110                           ${ASAN_BLACKLIST_FILE})
111  list(APPEND ${obj_list} ${output_obj})
112endmacro()
113
114# Link ASan unit test for a given architecture from a set
115# of objects in ${ARGN}.
116macro(add_asan_test test_suite test_name arch)
117  get_target_flags_for_arch(${arch} TARGET_LINK_FLAGS)
118  add_compiler_rt_test(${test_suite} ${test_name}
119                       OBJECTS ${ARGN}
120                       DEPS ${ASAN_RUNTIME_LIBRARIES} ${ARGN}
121                       LINK_FLAGS ${ASAN_LINK_FLAGS}
122                                  ${TARGET_LINK_FLAGS})
123endmacro()
124
125# Main AddressSanitizer unit tests.
126add_custom_target(AsanUnitTests)
127set_target_properties(AsanUnitTests PROPERTIES FOLDER "ASan unit tests")
128# ASan benchmarks (not actively used now).
129add_custom_target(AsanBenchmarks)
130set_target_properties(AsanBenchmarks PROPERTIES FOLDER "Asan benchmarks")
131
132set(ASAN_NOINST_TEST_SOURCES
133  asan_noinst_test.cc
134  asan_test_main.cc)
135set(ASAN_INST_TEST_SOURCES
136  asan_globals_test.cc
137  asan_test.cc
138  asan_oob_test.cc
139  asan_mem_test.cc
140  asan_str_test.cc)
141
142# Adds ASan unit tests and benchmarks for architecture.
143macro(add_asan_tests_for_arch arch)
144  # Build gtest instrumented with ASan.
145  set(ASAN_INST_GTEST)
146  asan_compile(ASAN_INST_GTEST ${COMPILER_RT_GTEST_SOURCE} ${arch} 
147                               ${ASAN_UNITTEST_INSTRUMENTED_CFLAGS})
148  # Instrumented tests.
149  set(ASAN_INST_TEST_OBJECTS)
150  foreach(src ${ASAN_INST_TEST_SOURCES})
151    asan_compile(ASAN_INST_TEST_OBJECTS ${src} ${arch}
152                 ${ASAN_UNITTEST_INSTRUMENTED_CFLAGS})
153  endforeach()
154  # Add Mac-specific tests.
155  if (APPLE)
156    asan_compile(ASAN_INST_TEST_OBJECTS asan_mac_test.cc ${arch}
157                 ${ASAN_UNITTEST_INSTRUMENTED_CFLAGS})
158    asan_compile(ASAN_INST_TEST_OBJECTS asan_mac_test_helpers.mm ${arch}
159                 ${ASAN_UNITTEST_INSTRUMENTED_CFLAGS} -ObjC)
160  endif()
161  # Uninstrumented tests.
162  set(ASAN_NOINST_TEST_OBJECTS)
163  foreach(src ${ASAN_NOINST_TEST_SOURCES})
164    asan_compile(ASAN_NOINST_TEST_OBJECTS ${src} ${arch}
165                 ${ASAN_UNITTEST_COMMON_CFLAGS})
166  endforeach()
167  # Link everything together.
168  add_asan_test(AsanUnitTests "Asan-${arch}-Test" ${arch}
169                ${ASAN_NOINST_TEST_OBJECTS}
170                ${ASAN_INST_TEST_OBJECTS} ${ASAN_INST_GTEST})
171
172  # Instrumented benchmarks.
173  set(ASAN_BENCHMARKS_OBJECTS)
174  asan_compile(ASAN_BENCHMARKS_OBJECTS asan_benchmarks_test.cc ${arch}
175               ${ASAN_UNITTEST_INSTRUMENTED_CFLAGS})
176  # Link benchmarks.
177  add_asan_test(AsanBenchmarks "Asan-${arch}-Benchmark" ${arch}
178                ${ASAN_BENCHMARKS_OBJECTS} ${ASAN_INST_GTEST})
179endmacro()
180
181if(COMPILER_RT_CAN_EXECUTE_TESTS)
182  foreach(arch ${ASAN_SUPPORTED_ARCH})
183    add_asan_tests_for_arch(${arch})
184  endforeach()
185endif()
186
187if(ANDROID)
188  # We assume that unit tests on Android are built in a build
189  # tree with fresh Clang as a host compiler.
190  add_library(asan_noinst_test OBJECT ${ASAN_NOINST_TEST_SOURCES})
191  set_target_compile_flags(asan_noinst_test ${ASAN_UNITTEST_COMMON_CFLAGS})
192  add_library(asan_inst_test OBJECT
193              ${ASAN_INST_TEST_SOURCES} ${COMPILER_RT_GTEST_SOURCE})  
194  set_target_compile_flags(asan_inst_test ${ASAN_UNITTEST_INSTRUMENTED_CFLAGS})
195  add_executable(AsanTest
196    $<TARGET_OBJECTS:asan_noinst_test>
197    $<TARGET_OBJECTS:asan_inst_test>
198  )
199  # Setup correct output directory and link flags.
200  set_target_properties(AsanTest PROPERTIES
201    RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
202  set_target_link_flags(AsanTest ${ASAN_LINK_FLAGS})
203  target_link_libraries(AsanTest clang_rt.asan-arm-android)
204  # Add unit test to test suite.
205  add_dependencies(AsanUnitTests AsanTest)
206endif()
207