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