summaryrefslogtreecommitdiff
path: root/lib/sanitizer_common/tests/CMakeLists.txt
blob: 342a73246e333ff152888bb43ef4203c1c7fc94b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
include(CompilerRTCompile)

clang_compiler_add_cxx_check()

# FIXME: use SANITIZER_COMMON_SUPPORTED_ARCH here
filter_available_targets(SANITIZER_UNITTEST_SUPPORTED_ARCH x86_64 i386 mips64 mips64el)

set(SANITIZER_UNITTESTS
  sanitizer_allocator_test.cc
  sanitizer_atomic_test.cc
  sanitizer_bitvector_test.cc
  sanitizer_bvgraph_test.cc
  sanitizer_common_test.cc
  sanitizer_deadlock_detector_test.cc
  sanitizer_flags_test.cc
  sanitizer_format_interceptor_test.cc
  sanitizer_ioctl_test.cc
  sanitizer_libc_test.cc
  sanitizer_linux_test.cc
  sanitizer_list_test.cc
  sanitizer_mutex_test.cc
  sanitizer_nolibc_test.cc
  sanitizer_posix_test.cc
  sanitizer_printf_test.cc
  sanitizer_procmaps_test.cc
  sanitizer_stackdepot_test.cc
  sanitizer_stacktrace_printer_test.cc
  sanitizer_stacktrace_test.cc
  sanitizer_stoptheworld_test.cc
  sanitizer_suppressions_test.cc
  sanitizer_symbolizer_test.cc
  sanitizer_test_main.cc
  sanitizer_thread_registry_test.cc)

set(SANITIZER_TEST_HEADERS
  sanitizer_pthread_wrappers.h
  sanitizer_test_config.h
  sanitizer_test_utils.h)
foreach(header ${SANITIZER_HEADERS})
  list(APPEND SANITIZER_TEST_HEADERS ${CMAKE_CURRENT_SOURCE_DIR}/../${header})
endforeach()

set(SANITIZER_TEST_CFLAGS_COMMON
  ${COMPILER_RT_TEST_CFLAGS}
  ${COMPILER_RT_GTEST_CFLAGS}
  -I${COMPILER_RT_SOURCE_DIR}/include
  -I${COMPILER_RT_SOURCE_DIR}/lib
  -I${COMPILER_RT_SOURCE_DIR}/lib/sanitizer_common
  -fno-rtti
  -O2
  -Werror=sign-compare
  -Wno-non-virtual-dtor)

if(MSVC)
  # Disable exceptions on Windows until they work reliably.
  list(APPEND SANITIZER_TEST_CFLAGS_COMMON -fno-exceptions -DGTEST_HAS_SEH=0)
endif()

# -gline-tables-only must be enough for these tests, so use it if possible.
if(COMPILER_RT_TEST_COMPILER_ID MATCHES "Clang")
  list(APPEND SANITIZER_TEST_CFLAGS_COMMON -gline-tables-only)
else()
  list(APPEND SANITIZER_TEST_CFLAGS_COMMON -g)
endif()

if(NOT MSVC)
  list(APPEND SANITIZER_TEST_LINK_FLAGS_COMMON --driver-mode=g++)
endif()

if(ANDROID)
  list(APPEND SANITIZER_TEST_LINK_FLAGS_COMMON -pie)
endif()

set(SANITIZER_TEST_LINK_LIBS)
append_list_if(ANDROID log SANITIZER_TEST_LINK_LIBS)
# NDK r10 requires -latomic almost always.
append_list_if(ANDROID atomic SANITIZER_TEST_LINK_LIBS)

append_list_if(COMPILER_RT_HAS_LIBDL -ldl SANITIZER_TEST_LINK_FLAGS_COMMON)
append_list_if(COMPILER_RT_HAS_LIBRT -lrt SANITIZER_TEST_LINK_FLAGS_COMMON)
append_list_if(COMPILER_RT_HAS_LIBPTHREAD -pthread SANITIZER_TEST_LINK_FLAGS_COMMON)
# x86_64 FreeBSD 9.2 additionally requires libc++ to build the tests. Also,
# 'libm' shall be specified explicitly to build i386 tests.
if(CMAKE_SYSTEM MATCHES "FreeBSD-9.2-RELEASE")
  list(APPEND SANITIZER_TEST_LINK_FLAGS_COMMON "-lc++ -lm")
endif()

include_directories(..)
include_directories(../..)

# Adds static library which contains sanitizer_common object file
# (universal binary on Mac and arch-specific object files on Linux).
macro(add_sanitizer_common_lib library)
  add_library(${library} STATIC ${ARGN})
  set_target_properties(${library} PROPERTIES
    ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
endmacro()

function(get_sanitizer_common_lib_for_arch arch lib lib_name)
  if(APPLE)
    set(tgt_name "RTSanitizerCommon.test.osx")
  else()
    set(tgt_name "RTSanitizerCommon.test.${arch}")
  endif()
  set(${lib} "${tgt_name}" PARENT_SCOPE)
  if(NOT MSVC)
    set(${lib_name} "lib${tgt_name}.a" PARENT_SCOPE)
  else()
    set(${lib_name} "${tgt_name}.lib" PARENT_SCOPE)
  endif()
endfunction()

# Sanitizer_common unit tests testsuite.
add_custom_target(SanitizerUnitTests)
set_target_properties(SanitizerUnitTests PROPERTIES
  FOLDER "Sanitizer unittests")

# Adds sanitizer tests for architecture.
macro(add_sanitizer_tests_for_arch arch)
  get_target_flags_for_arch(${arch} TARGET_FLAGS)
  set(SANITIZER_TEST_SOURCES ${SANITIZER_UNITTESTS}
                             ${COMPILER_RT_GTEST_SOURCE})
  set(SANITIZER_TEST_COMPILE_DEPS ${SANITIZER_TEST_HEADERS})
  if(NOT COMPILER_RT_STANDALONE_BUILD)
    list(APPEND SANITIZER_TEST_COMPILE_DEPS gtest)
  endif()
  set(SANITIZER_TEST_OBJECTS)
  foreach(source ${SANITIZER_TEST_SOURCES})
    get_filename_component(basename ${source} NAME)
    set(output_obj "${basename}.${arch}.o")
    clang_compile(${output_obj} ${source}
                  CFLAGS ${SANITIZER_TEST_CFLAGS_COMMON} ${TARGET_FLAGS}
                  DEPS ${SANITIZER_TEST_COMPILE_DEPS})
    list(APPEND SANITIZER_TEST_OBJECTS ${output_obj})
  endforeach()
  get_sanitizer_common_lib_for_arch(${arch} SANITIZER_COMMON_LIB
                                    SANITIZER_COMMON_LIB_NAME)
  # Add unittest target.
  set(SANITIZER_TEST_NAME "Sanitizer-${arch}-Test")
  add_compiler_rt_test(SanitizerUnitTests ${SANITIZER_TEST_NAME}
                       OBJECTS ${SANITIZER_TEST_OBJECTS}
                               ${SANITIZER_COMMON_LIB_NAME}
                       DEPS ${SANITIZER_TEST_OBJECTS} ${SANITIZER_COMMON_LIB}
                       LINK_FLAGS ${SANITIZER_TEST_LINK_FLAGS_COMMON}
                                  ${TARGET_FLAGS})

  if("${CMAKE_SYSTEM_NAME}" STREQUAL "Linux" AND "${arch}" STREQUAL "x86_64")
    # Test that the libc-independent part of sanitizer_common is indeed
    # independent of libc, by linking this binary without libc (here) and
    # executing it (unit test in sanitizer_nolibc_test.cc).
    clang_compile(sanitizer_nolibc_test_main.${arch}.o
                  sanitizer_nolibc_test_main.cc
                  CFLAGS ${SANITIZER_TEST_CFLAGS_COMMON} ${TARGET_FLAGS}
                  DEPS ${SANITIZER_TEST_COMPILE_DEPS})
    add_compiler_rt_test(SanitizerUnitTests "Sanitizer-${arch}-Test-Nolibc"
                         OBJECTS sanitizer_nolibc_test_main.${arch}.o
                                 -Wl,-whole-archive
                                 libRTSanitizerCommon.test.nolibc.${arch}.a
                                 -Wl,-no-whole-archive
                         DEPS sanitizer_nolibc_test_main.${arch}.o
                              RTSanitizerCommon.test.nolibc.${arch}
                         LINK_FLAGS -nostdlib ${TARGET_FLAGS})
  endif()
endmacro()

if(COMPILER_RT_CAN_EXECUTE_TESTS AND NOT ANDROID)
  # We use just-built clang to build sanitizer_common unittests, so we must
  # be sure that produced binaries would work.
  if(APPLE)
    add_sanitizer_common_lib("RTSanitizerCommon.test.osx"
                             $<TARGET_OBJECTS:RTSanitizerCommon.osx>)
  else()
    if(CAN_TARGET_x86_64)
      add_sanitizer_common_lib("RTSanitizerCommon.test.nolibc.x86_64"
                               $<TARGET_OBJECTS:RTSanitizerCommon.x86_64>
                               $<TARGET_OBJECTS:RTSanitizerCommonNoLibc.x86_64>)
    endif()
    foreach(arch ${SANITIZER_UNITTEST_SUPPORTED_ARCH})
      add_sanitizer_common_lib("RTSanitizerCommon.test.${arch}"
                               $<TARGET_OBJECTS:RTSanitizerCommon.${arch}>
                               $<TARGET_OBJECTS:RTSanitizerCommonLibc.${arch}>)
    endforeach()
  endif()
  foreach(arch ${SANITIZER_UNITTEST_SUPPORTED_ARCH})
    add_sanitizer_tests_for_arch(${arch})
  endforeach()
endif()

if(ANDROID)
  foreach(arch ${SANITIZER_COMMON_SUPPORTED_ARCH})
    add_executable(SanitizerTest
      ${SANITIZER_UNITTESTS}
      ${COMPILER_RT_GTEST_SOURCE}
      $<TARGET_OBJECTS:RTSanitizerCommon.${arch}>
      $<TARGET_OBJECTS:RTSanitizerCommonLibc.${arch}>)
    set_target_compile_flags(SanitizerTest
      ${SANITIZER_COMMON_CFLAGS}
      ${SANITIZER_TEST_CFLAGS_COMMON})
    # Setup correct output directory and link flags.
    set_target_properties(SanitizerTest PROPERTIES
      RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
    set_target_link_flags(SanitizerTest ${SANITIZER_TEST_LINK_FLAGS_COMMON})
    target_link_libraries(SanitizerTest ${SANITIZER_TEST_LINK_LIBS})
    # Add unit test to test suite.
    add_dependencies(SanitizerUnitTests SanitizerTest)
  endforeach()
endif()