CMakeLists.txt revision 6cbfae439b81221d2250ffe0331958f130259755
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_FLEXIBLE_MAPPING_AND_OFFSET=1
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_LOW_MEMORY=1
58    -DASAN_NEEDS_SEGV=0)
59else()
60  list(APPEND ASAN_UNITTEST_COMMON_CFLAGS
61    -DASAN_LOW_MEMORY=0
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  -mllvm "-asan-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
130# Adds ASan unit tests and benchmarks for architecture.
131macro(add_asan_tests_for_arch arch)
132  # Build gtest instrumented with ASan.
133  set(ASAN_INST_GTEST)
134  asan_compile(ASAN_INST_GTEST ${COMPILER_RT_GTEST_SOURCE} ${arch} 
135                               ${ASAN_UNITTEST_INSTRUMENTED_CFLAGS})
136  # Instrumented tests.
137  set(ASAN_INST_TEST_OBJECTS)
138  asan_compile(ASAN_INST_TEST_OBJECTS asan_globals_test.cc ${arch}
139               ${ASAN_UNITTEST_INSTRUMENTED_CFLAGS})
140  asan_compile(ASAN_INST_TEST_OBJECTS asan_test.cc ${arch}
141               ${ASAN_UNITTEST_INSTRUMENTED_CFLAGS})
142  asan_compile(ASAN_INST_TEST_OBJECTS asan_oob_test.cc ${arch}
143               ${ASAN_UNITTEST_INSTRUMENTED_CFLAGS})
144  asan_compile(ASAN_INST_TEST_OBJECTS asan_mem_test.cc ${arch}
145               ${ASAN_UNITTEST_INSTRUMENTED_CFLAGS})
146  if (APPLE)
147    asan_compile(ASAN_INST_TEST_OBJECTS asan_mac_test.cc ${arch}
148                 ${ASAN_UNITTEST_INSTRUMENTED_CFLAGS})
149    asan_compile(ASAN_INST_TEST_OBJECTS asan_mac_test_helpers.mm ${arch}
150                 ${ASAN_UNITTEST_INSTRUMENTED_CFLAGS} -ObjC)
151  endif()
152  # Uninstrumented tests.
153  set(ASAN_NOINST_TEST_OBJECTS)
154  asan_compile(ASAN_NOINST_TEST_OBJECTS asan_noinst_test.cc ${arch}
155               ${ASAN_UNITTEST_COMMON_CFLAGS})
156  asan_compile(ASAN_NOINST_TEST_OBJECTS asan_test_main.cc ${arch}
157               ${ASAN_UNITTEST_COMMON_CFLAGS})
158  # Link everything together.
159  add_asan_test(AsanUnitTests "Asan-${arch}-Test" ${arch}
160                ${ASAN_NOINST_TEST_OBJECTS}
161                ${ASAN_INST_TEST_OBJECTS} ${ASAN_INST_GTEST})
162
163  # Instrumented benchmarks.
164  set(ASAN_BENCHMARKS_OBJECTS)
165  asan_compile(ASAN_BENCHMARKS_OBJECTS asan_benchmarks_test.cc ${arch}
166               ${ASAN_UNITTEST_INSTRUMENTED_CFLAGS})
167  # Link benchmarks.
168  add_asan_test(AsanBenchmarks "Asan-${arch}-Benchmark" ${arch}
169                ${ASAN_BENCHMARKS_OBJECTS} ${ASAN_INST_GTEST})
170endmacro()
171
172if(COMPILER_RT_CAN_EXECUTE_TESTS)
173  foreach(arch ${ASAN_SUPPORTED_ARCH})
174    add_asan_tests_for_arch(${arch})
175  endforeach()
176endif()
177
178if(ANDROID)
179  # We assume that unit tests on Android are built in a build
180  # tree with fresh Clang as a host compiler.
181  set(ASAN_NOINST_TEST_SOURCES asan_noinst_test.cc asan_test_main.cc)
182  set(ASAN_INST_TEST_SOURCES asan_globals_test.cc asan_test.cc
183    asan_oob_test.cc asan_mem_test.cc)
184  add_library(asan_noinst_test OBJECT ${ASAN_NOINST_TEST_SOURCES})
185  set_target_compile_flags(asan_noinst_test ${ASAN_UNITTEST_COMMON_CFLAGS})
186  add_library(asan_inst_test OBJECT
187              ${ASAN_INST_TEST_SOURCES} ${COMPILER_RT_GTEST_SOURCE})  
188  set_target_compile_flags(asan_inst_test ${ASAN_UNITTEST_INSTRUMENTED_CFLAGS})
189  add_executable(AsanTest
190    $<TARGET_OBJECTS:asan_noinst_test>
191    $<TARGET_OBJECTS:asan_inst_test>
192  )
193  # Setup correct output directory and link flags.
194  get_unittest_directory(OUTPUT_DIR)
195  set_target_properties(AsanTest PROPERTIES
196    RUNTIME_OUTPUT_DIRECTORY ${OUTPUT_DIR})
197  set_target_link_flags(AsanTest ${ASAN_LINK_FLAGS})
198  target_link_libraries(AsanTest clang_rt.asan-arm-android)
199  # Add unit test to test suite.
200  add_dependencies(AsanUnitTests AsanTest)
201endif()
202