CMakeLists.txt revision 34fc56c43f60be0b85a0e3ce30658fd98951f0b8
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)
13
14include_directories(..)
15include_directories(../..)
16
17set(ASAN_UNITTEST_COMMON_CFLAGS
18  -Wall
19  -Wno-format
20  -fvisibility=hidden
21  -g
22  -O2
23)
24
25# Use -D instead of definitions to please custom compile command.
26if(ANDROID)
27  list(APPEND ASAN_UNITTEST_COMMON_CFLAGS
28    -DASAN_LOW_MEMORY=1
29    -DASAN_HAS_BLACKLIST=1
30    -DASAN_HAS_EXCEPTIONS=1
31    -DASAN_NEEDS_SEGV=0
32    -DASAN_UAR=0
33    -fPIE
34  )
35else()
36  list(APPEND ASAN_UNITTEST_COMMON_CFLAGS
37    -DASAN_HAS_BLACKLIST=1
38    -DASAN_HAS_EXCEPTIONS=1
39    -DASAN_NEEDS_SEGV=1
40    -DASAN_UAR=0
41  )
42endif()
43
44# Support 64-bit and 32-bit builds.
45if(LLVM_BUILD_32_BITS)
46  list(APPEND ASAN_UNITTEST_COMMON_CFLAGS -m32)
47else()
48  list(APPEND ASAN_UNITTEST_COMMON_CFLAGS -m64)
49endif()
50
51set(ASAN_GTEST_INCLUDE_CFLAGS
52  -I${LLVM_MAIN_SRC_DIR}/utils/unittest/googletest/include
53  -I${LLVM_MAIN_SRC_DIR}/include
54  -I${LLVM_BINARY_DIR}/include
55  -D__STDC_CONSTANT_MACROS
56  -D__STDC_LIMIT_MACROS
57)
58
59set(ASAN_UNITTEST_INSTRUMENTED_CFLAGS
60  ${ASAN_UNITTEST_COMMON_CFLAGS}
61  ${ASAN_GTEST_INCLUDE_CFLAGS}
62  -faddress-sanitizer
63  -mllvm "-asan-blacklist=${CMAKE_CURRENT_SOURCE_DIR}/asan_test.ignore"
64  -mllvm -asan-stack=1
65  -mllvm -asan-globals=1
66  -mllvm -asan-mapping-scale=0        # default will be used
67  -mllvm -asan-mapping-offset-log=-1  # default will be used
68  -mllvm -asan-use-after-return=0
69)
70
71function(add_asan_test testsuite testname)
72  add_unittest(${testsuite} ${testname} ${ARGN})
73  if (APPLE)
74    # Darwin-specific linker flags.
75    set_property(TARGET ${testname} APPEND PROPERTY
76                 LINK_FLAGS "-framework Foundation")
77    target_link_libraries(${testname} clang_rt.asan_osx)
78  elseif (ANDROID)
79    target_link_libraries(${testname} clang_rt.asan-arm-android)
80  elseif (UNIX)
81    # Linux-specific linker flags.
82    set_property(TARGET ${testname} APPEND PROPERTY
83                 LINK_FLAGS "-lpthread -ldl -rdynamic")
84    if(LLVM_BUILD_32_BITS)
85      target_link_libraries(${testname} clang_rt.asan-i386)
86    else()
87      target_link_libraries(${testname} clang_rt.asan-x86_64)
88    endif()
89  endif()
90  set(add_compile_flags "")
91  get_property(compile_flags TARGET ${testname} PROPERTY COMPILE_FLAGS)
92  foreach(arg ${ASAN_UNITTEST_COMMON_CFLAGS})
93    set(add_compile_flags "${add_compile_flags} ${arg}")
94  endforeach(arg ${ASAN_UNITTEST_COMMON_CFLAGS})
95  set_property(TARGET ${testname} PROPERTY COMPILE_FLAGS
96               "${compile_flags} ${add_compile_flags}")
97endfunction()
98
99set(ASAN_NOINST_TEST_SOURCES
100  asan_noinst_test.cc
101  asan_break_optimization.cc
102)
103
104set(ASAN_INST_TEST_OBJECTS)
105
106# We only support building instrumented tests when we're not cross compiling
107# and targeting a unix-like system where we can predict viable compilation and
108# linking strategies.
109# We use a different approach to build these tests for Android. See below.
110if("${CMAKE_HOST_SYSTEM}" STREQUAL "${CMAKE_SYSTEM}" AND UNIX AND NOT ANDROID)
111
112  # This function is a custom routine to manage manually compiling source files
113  # for unit tests with the just-built Clang binary, using the ASan
114  # instrumentation, and linking them into a test executable.
115  function(add_asan_compile_command source extra_cflags)
116    set(output_obj "${source}.asan.o")
117    add_custom_command(
118      OUTPUT ${output_obj}
119      COMMAND clang
120              ${ASAN_UNITTEST_INSTRUMENTED_CFLAGS}
121              ${extra_cflags}
122              -c -o "${output_obj}"
123              ${CMAKE_CURRENT_SOURCE_DIR}/${source}
124      MAIN_DEPENDENCY ${source}
125      DEPENDS clang ${ASAN_RUNTIME_LIBRARIES} ${ARGN}
126      )
127  endfunction()
128
129  add_asan_compile_command(asan_globals_test.cc "")
130  add_asan_compile_command(asan_test.cc "")
131  list(APPEND ASAN_INST_TEST_OBJECTS asan_globals_test.cc.asan.o
132                                     asan_test.cc.asan.o)
133  if (APPLE)
134    add_asan_compile_command(asan_mac_test.mm "-ObjC")
135    list(APPEND ASAN_INST_TEST_OBJECTS asan_mac_test.mm.asan.o)
136  endif()
137
138  # Build benchmarks test instrumented with AddressSanitizer.
139  add_asan_compile_command(asan_benchmarks_test.cc "")
140  add_custom_target(AsanBenchmarks)
141  set_target_properties(AsanBenchmarks PROPERTIES FOLDER "Asan benchmarks")
142  add_asan_test(AsanBenchmarks AsanBenchmark asan_break_optimization.cc
143                                             asan_benchmarks_test.cc.asan.o)
144endif()
145
146# Main AddressSanitizer unit tests.
147add_custom_target(AsanUnitTests)
148set_target_properties(AsanUnitTests PROPERTIES FOLDER "ASan unit tests")
149
150if(ANDROID)
151  set(ASAN_INST_TEST_SOURCES asan_globals_test.cc asan_test.cc)
152  add_library(asan_noinst_test OBJECT
153    ${ASAN_NOINST_TEST_SOURCES}
154    )
155  set_target_compile_flags(asan_noinst_test
156    ${ASAN_UNITTEST_COMMON_CFLAGS} ${ASAN_GTEST_INCLUDE_CFLAGS}
157    )
158  add_asan_test(AsanUnitTests AsanTest
159    ${ASAN_INST_TEST_SOURCES}
160    $<TARGET_OBJECTS:asan_noinst_test>
161    )
162  set_target_compile_flags(AsanTest
163    ${ASAN_UNITTEST_INSTRUMENTED_CFLAGS} ${ASAN_GTEST_INCLUDE_CFLAGS}
164    )
165  set_target_link_flags(AsanTest
166    -pie
167    )
168else()
169  add_asan_test(AsanUnitTests AsanTest ${ASAN_NOINST_TEST_SOURCES}
170    ${ASAN_INST_TEST_OBJECTS})
171endif()
172