Home | History | Annotate | Download | only in tests
      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 
     12 include(CheckCXXCompilerFlag)
     13 include(CompilerRTCompile)
     14 
     15 include_directories(..)
     16 include_directories(../..)
     17 
     18 set(ASAN_UNITTEST_HEADERS
     19   asan_mac_test.h
     20   asan_test_config.h
     21   asan_test_utils.h)
     22 
     23 set(ASAN_UNITTEST_COMMON_CFLAGS
     24   ${COMPILER_RT_UNITTEST_CFLAGS}
     25   ${COMPILER_RT_GTEST_CFLAGS}
     26   -I${COMPILER_RT_SOURCE_DIR}/include
     27   -I${COMPILER_RT_SOURCE_DIR}/lib
     28   -I${COMPILER_RT_SOURCE_DIR}/lib/asan
     29   -I${COMPILER_RT_SOURCE_DIR}/lib/sanitizer_common/tests
     30   -fno-rtti
     31   -O2
     32   -Wno-format
     33   -Werror=sign-compare
     34   -Wno-non-virtual-dtor)
     35 append_list_if(COMPILER_RT_HAS_WVARIADIC_MACROS_FLAG -Wno-variadic-macros ASAN_UNITTEST_COMMON_CFLAGS)
     36 
     37 # This will ensure the target linker is used
     38 # during cross compilation
     39 set(ASAN_UNITTEST_COMMON_LINKFLAGS
     40   ${COMPILER_RT_UNITTEST_LINKFLAGS})
     41 
     42 # -gline-tables-only must be enough for ASan, so use it if possible.
     43 if(COMPILER_RT_TEST_COMPILER_ID MATCHES "Clang")
     44   list(APPEND ASAN_UNITTEST_COMMON_CFLAGS -gline-tables-only)
     45 else()
     46   list(APPEND ASAN_UNITTEST_COMMON_CFLAGS -g)
     47 endif()
     48 if(MSVC)
     49   list(APPEND ASAN_UNITTEST_COMMON_CFLAGS -gcodeview)
     50 endif()
     51 list(APPEND ASAN_UNITTEST_COMMON_LINKFLAGS -g)
     52 
     53 # Use -D instead of definitions to please custom compile command.
     54 list(APPEND ASAN_UNITTEST_COMMON_CFLAGS
     55   -DASAN_HAS_BLACKLIST=1
     56   -DASAN_HAS_EXCEPTIONS=1
     57   -DASAN_UAR=0)
     58 
     59 if(APPLE)
     60   list(APPEND ASAN_UNITTEST_COMMON_CFLAGS ${DARWIN_osx_CFLAGS})
     61   list(APPEND ASAN_UNITTEST_COMMON_LINKFLAGS ${DARWIN_osx_LINKFLAGS})
     62 endif()
     63 
     64 if(MSVC)
     65   # Disable exceptions on Windows until they work reliably.
     66   list(APPEND ASAN_UNITTEST_COMMON_CFLAGS -fno-exceptions -DGTEST_HAS_SEH=0)
     67 endif()
     68 
     69 set(ASAN_BLACKLIST_FILE "${CMAKE_CURRENT_SOURCE_DIR}/asan_test.ignore")
     70 set(ASAN_UNITTEST_INSTRUMENTED_CFLAGS
     71   ${ASAN_UNITTEST_COMMON_CFLAGS}
     72   -fsanitize=address
     73   "-fsanitize-blacklist=${ASAN_BLACKLIST_FILE}"
     74 )
     75 if(CAN_TARGET_x86_64 OR CAN_TARGET_i386)
     76   list(APPEND ASAN_UNITTEST_INSTRUMENTED_CFLAGS -mllvm -asan-instrument-assembly)
     77 endif()
     78 
     79 if(NOT MSVC)
     80   list(APPEND ASAN_UNITTEST_COMMON_LINKFLAGS --driver-mode=g++)
     81 endif()
     82 
     83 # x86_64 FreeBSD 9.2 additionally requires libc++ to build the tests.
     84 if(CMAKE_SYSTEM MATCHES "FreeBSD-9.2-RELEASE")
     85   list(APPEND ASAN_UNITTEST_COMMON_LINKFLAGS "-lc++")
     86 endif()
     87 
     88 # Unit tests on Mac depend on Foundation.
     89 if(APPLE)
     90   list(APPEND ASAN_UNITTEST_COMMON_LINKFLAGS -framework Foundation)
     91 endif()
     92 if(ANDROID)
     93   list(APPEND ASAN_UNITTEST_COMMON_LINKFLAGS -pie)
     94 endif()
     95 
     96 set(ASAN_UNITTEST_INSTRUMENTED_LINKFLAGS
     97   ${ASAN_UNITTEST_COMMON_LINKFLAGS})
     98 list(APPEND ASAN_UNITTEST_INSTRUMENTED_LINKFLAGS -fsanitize=address)
     99 
    100 set(ASAN_DYNAMIC_UNITTEST_INSTRUMENTED_LINKFLAGS
    101   ${ASAN_UNITTEST_INSTRUMENTED_LINKFLAGS}
    102   -shared-libasan)
    103 
    104 set(ASAN_UNITTEST_INSTRUMENTED_LIBS)
    105 # NDK r10 requires -latomic almost always.
    106 append_list_if(ANDROID atomic ASAN_UNITTEST_INSTRUMENTED_LIBS)
    107 
    108 set(ASAN_UNITTEST_NOINST_LINKFLAGS ${ASAN_UNITTEST_COMMON_LINKFLAGS})
    109 append_list_if(COMPILER_RT_HAS_LIBM -lm ASAN_UNITTEST_NOINST_LINKFLAGS)
    110 append_list_if(COMPILER_RT_HAS_LIBDL -ldl ASAN_UNITTEST_NOINST_LINKFLAGS)
    111 append_list_if(COMPILER_RT_HAS_LIBRT -lrt ASAN_UNITTEST_NOINST_LINKFLAGS)
    112 append_list_if(COMPILER_RT_HAS_LIBPTHREAD -pthread ASAN_UNITTEST_NOINST_LINKFLAGS)
    113 append_list_if(COMPILER_RT_HAS_LIBPTHREAD -pthread
    114           ASAN_DYNAMIC_UNITTEST_INSTRUMENTED_LINKFLAGS)
    115 
    116 # TODO(eugenis): move all -l flags above to _LIBS?
    117 set(ASAN_UNITTEST_NOINST_LIBS)
    118 append_list_if(COMPILER_RT_HAS_LIBLOG log ASAN_UNITTEST_NOINST_LIBS)
    119 # NDK r10 requires -latomic almost always.
    120 append_list_if(ANDROID atomic ASAN_UNITTEST_NOINST_LIBS)
    121 
    122 # Compile source for the given architecture, using compiler
    123 # options in ${ARGN}, and add it to the object list.
    124 macro(asan_compile obj_list source arch kind)
    125   get_filename_component(basename ${source} NAME)
    126   if(CMAKE_CONFIGURATION_TYPES)
    127     set(output_obj "${CMAKE_CFG_INTDIR}/${obj_list}.${basename}.${arch}${kind}.o")
    128   else()
    129     set(output_obj "${obj_list}.${basename}.${arch}${kind}.o")
    130   endif()
    131   get_target_flags_for_arch(${arch} TARGET_CFLAGS)
    132   set(COMPILE_DEPS ${ASAN_UNITTEST_HEADERS} ${ASAN_BLACKLIST_FILE})
    133   if(NOT COMPILER_RT_STANDALONE_BUILD)
    134     list(APPEND COMPILE_DEPS gtest asan)
    135   endif()
    136   clang_compile(${output_obj} ${source}
    137                 CFLAGS ${ARGN} ${TARGET_CFLAGS}
    138                 DEPS ${COMPILE_DEPS})
    139   list(APPEND ${obj_list} ${output_obj})
    140 endmacro()
    141 
    142 # Link ASan unit test for a given architecture from a set
    143 # of objects in with given linker flags.
    144 macro(add_asan_test test_suite test_name arch kind)
    145   cmake_parse_arguments(TEST "WITH_TEST_RUNTIME" "" "OBJECTS;LINKFLAGS;SUBDIR" ${ARGN})
    146   get_target_flags_for_arch(${arch} TARGET_LINK_FLAGS)
    147   set(TEST_DEPS ${TEST_OBJECTS})
    148   if(NOT COMPILER_RT_STANDALONE_BUILD)
    149     list(APPEND TEST_DEPS asan)
    150   endif()
    151   if(TEST_WITH_TEST_RUNTIME)
    152     list(APPEND TEST_DEPS ${ASAN_TEST_RUNTIME})
    153     if(CMAKE_CONFIGURATION_TYPES)
    154      set(configuration_path "${CMAKE_CFG_INTDIR}/")
    155     else()
    156      set(configuration_path "")
    157     endif()
    158     if(NOT MSVC)
    159       set(asan_test_runtime_path ${configuration_path}lib${ASAN_TEST_RUNTIME}.a)
    160     else()
    161       set(asan_test_runtime_path ${configuration_path}${ASAN_TEST_RUNTIME}.lib)
    162     endif()
    163     list(APPEND TEST_OBJECTS ${asan_test_runtime_path})
    164   endif()
    165   add_compiler_rt_test(${test_suite} ${test_name}
    166                        SUBDIR ${TEST_SUBDIR}
    167                        OBJECTS ${TEST_OBJECTS}
    168                        DEPS ${TEST_DEPS}
    169                        LINK_FLAGS ${TEST_LINKFLAGS}
    170                                   ${TARGET_LINK_FLAGS})
    171 endmacro()
    172 
    173 # Main AddressSanitizer unit tests.
    174 add_custom_target(AsanUnitTests)
    175 set_target_properties(AsanUnitTests PROPERTIES FOLDER "Compiler-RT Tests")
    176 
    177 # AddressSanitizer unit tests with dynamic runtime (on platforms where it's
    178 # not the default).
    179 add_custom_target(AsanDynamicUnitTests)
    180 set_target_properties(AsanDynamicUnitTests PROPERTIES FOLDER "Compiler-RT Tests")
    181 # ASan benchmarks (not actively used now).
    182 add_custom_target(AsanBenchmarks)
    183 set_target_properties(AsanBenchmarks PROPERTIES FOLDER "Compiler-RT Tests")
    184 
    185 set(ASAN_NOINST_TEST_SOURCES
    186   ${COMPILER_RT_GTEST_SOURCE}
    187   asan_fake_stack_test.cc
    188   asan_noinst_test.cc
    189   asan_test_main.cc)
    190 
    191 set(ASAN_INST_TEST_SOURCES
    192   ${COMPILER_RT_GTEST_SOURCE}
    193   asan_asm_test.cc
    194   asan_globals_test.cc
    195   asan_interface_test.cc
    196   asan_test.cc
    197   asan_oob_test.cc
    198   asan_mem_test.cc
    199   asan_str_test.cc
    200   asan_test_main.cc)
    201 if(APPLE)
    202   list(APPEND ASAN_INST_TEST_SOURCES asan_mac_test.cc)
    203 endif()
    204 
    205 set(ASAN_BENCHMARKS_SOURCES
    206   ${COMPILER_RT_GTEST_SOURCE}
    207   asan_benchmarks_test.cc)
    208 
    209 # Adds ASan unit tests and benchmarks for architecture.
    210 macro(add_asan_tests_for_arch_and_kind arch kind)
    211   # Instrumented tests.
    212   set(ASAN_INST_TEST_OBJECTS)
    213   foreach(src ${ASAN_INST_TEST_SOURCES})
    214     asan_compile(ASAN_INST_TEST_OBJECTS ${src} ${arch} ${kind}
    215       ${ASAN_UNITTEST_INSTRUMENTED_CFLAGS} ${ARGN})
    216   endforeach()
    217   if (APPLE)
    218     # Add Mac-specific helper.
    219     asan_compile(ASAN_INST_TEST_OBJECTS asan_mac_test_helpers.mm ${arch} ${kind}
    220                  ${ASAN_UNITTEST_INSTRUMENTED_CFLAGS} -ObjC ${ARGN})
    221   endif()
    222 
    223   # Create the 'default' folder where ASAN tests are produced.
    224   if(CMAKE_CONFIGURATION_TYPES)
    225     foreach(build_mode ${CMAKE_CONFIGURATION_TYPES})
    226       file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/default/${build_mode}")
    227     endforeach()
    228   else()
    229     file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/default")
    230   endif()
    231 
    232   add_asan_test(AsanUnitTests "Asan-${arch}${kind}-Test"
    233                 ${arch} ${kind} SUBDIR "default"
    234                 OBJECTS ${ASAN_INST_TEST_OBJECTS}
    235                 LINKFLAGS ${ASAN_UNITTEST_INSTRUMENTED_LINKFLAGS})
    236   if(COMPILER_RT_ASAN_HAS_STATIC_RUNTIME)
    237     # Create the 'dynamic' folder where ASAN tests are produced.
    238     if(CMAKE_CONFIGURATION_TYPES)
    239       foreach(build_mode ${CMAKE_CONFIGURATION_TYPES})
    240         file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/dynamic/${build_mode}")
    241       endforeach()
    242     else()
    243       file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/dynamic")
    244     endif()
    245 
    246     add_asan_test(AsanDynamicUnitTests "Asan-${arch}${kind}-Dynamic-Test"
    247                   ${arch} ${kind} SUBDIR "dynamic"
    248                   OBJECTS ${ASAN_INST_TEST_OBJECTS}
    249                   LINKFLAGS ${ASAN_DYNAMIC_UNITTEST_INSTRUMENTED_LINKFLAGS})
    250   endif()
    251 
    252   # Add static ASan runtime that will be linked with uninstrumented tests.
    253   set(ASAN_TEST_RUNTIME RTAsanTest.${arch}${kind})
    254   if(APPLE)
    255     set(ASAN_TEST_RUNTIME_OBJECTS
    256       $<TARGET_OBJECTS:RTAsan_dynamic.osx>
    257       $<TARGET_OBJECTS:RTInterception.osx>
    258       $<TARGET_OBJECTS:RTSanitizerCommon.osx>
    259       $<TARGET_OBJECTS:RTSanitizerCommonLibc.osx>
    260       $<TARGET_OBJECTS:RTLSanCommon.osx>
    261       $<TARGET_OBJECTS:RTUbsan.osx>)
    262   else()
    263     set(ASAN_TEST_RUNTIME_OBJECTS
    264       $<TARGET_OBJECTS:RTAsan.${arch}>
    265       $<TARGET_OBJECTS:RTAsan_cxx.${arch}>
    266       $<TARGET_OBJECTS:RTInterception.${arch}>
    267       $<TARGET_OBJECTS:RTSanitizerCommon.${arch}>
    268       $<TARGET_OBJECTS:RTSanitizerCommonLibc.${arch}>
    269       $<TARGET_OBJECTS:RTLSanCommon.${arch}>
    270       $<TARGET_OBJECTS:RTUbsan.${arch}>
    271       $<TARGET_OBJECTS:RTUbsan_cxx.${arch}>)
    272   endif()
    273   add_library(${ASAN_TEST_RUNTIME} STATIC ${ASAN_TEST_RUNTIME_OBJECTS})
    274   set_target_properties(${ASAN_TEST_RUNTIME} PROPERTIES
    275     ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
    276     FOLDER "Compiler-RT Runtime tests")
    277   # Uninstrumented tests.
    278   set(ASAN_NOINST_TEST_OBJECTS)
    279   foreach(src ${ASAN_NOINST_TEST_SOURCES})
    280     asan_compile(ASAN_NOINST_TEST_OBJECTS ${src} ${arch} ${kind}
    281                  ${ASAN_UNITTEST_COMMON_CFLAGS} ${ARGN})
    282   endforeach()
    283   add_asan_test(AsanUnitTests "Asan-${arch}${kind}-Noinst-Test"
    284                 ${arch} ${kind} SUBDIR "default"
    285                 OBJECTS ${ASAN_NOINST_TEST_OBJECTS}
    286                 LINKFLAGS ${ASAN_UNITTEST_NOINST_LINKFLAGS}
    287                 WITH_TEST_RUNTIME)
    288 
    289   # Benchmarks.
    290   set(ASAN_BENCHMARKS_OBJECTS)
    291   foreach(src ${ASAN_BENCHMARKS_SOURCES})
    292     asan_compile(ASAN_BENCHMARKS_OBJECTS ${src} ${arch} ${kind}
    293                  ${ASAN_UNITTEST_INSTRUMENTED_CFLAGS} ${ARGN})
    294   endforeach()
    295   add_asan_test(AsanBenchmarks "Asan-${arch}${kind}-Benchmark"
    296                 ${arch} ${kind} SUBDIR "default"
    297                 OBJECTS ${ASAN_BENCHMARKS_OBJECTS}
    298                 LINKFLAGS ${ASAN_UNITTEST_INSTRUMENTED_LINKFLAGS})
    299 endmacro()
    300 
    301 if(COMPILER_RT_CAN_EXECUTE_TESTS AND NOT ANDROID)
    302   set(ASAN_TEST_ARCH ${ASAN_SUPPORTED_ARCH})
    303   if(APPLE)
    304     darwin_filter_host_archs(ASAN_SUPPORTED_ARCH ASAN_TEST_ARCH)
    305   endif()
    306   foreach(arch ${ASAN_TEST_ARCH})
    307     add_asan_tests_for_arch_and_kind(${arch} "-inline")
    308     add_asan_tests_for_arch_and_kind(${arch} "-with-calls"
    309       -mllvm -asan-instrumentation-with-call-threshold=0)
    310   endforeach()
    311 endif()
    312 
    313 if(ANDROID)
    314   foreach(arch ${ASAN_SUPPORTED_ARCH})
    315     # Test w/o ASan instrumentation. Link it with ASan statically.
    316     add_executable(AsanNoinstTest # FIXME: .arch?
    317       $<TARGET_OBJECTS:RTAsan.${arch}>
    318       $<TARGET_OBJECTS:RTInterception.${arch}>
    319       $<TARGET_OBJECTS:RTSanitizerCommon.${arch}>
    320       $<TARGET_OBJECTS:RTSanitizerCommonLibc.${arch}>
    321       $<TARGET_OBJECTS:RTUbsan.${arch}>
    322       $<TARGET_OBJECTS:RTUbsan_cxx.${arch}>
    323       ${COMPILER_RT_GTEST_SOURCE}
    324       ${ASAN_NOINST_TEST_SOURCES})
    325     set_target_compile_flags(AsanNoinstTest ${ASAN_UNITTEST_COMMON_CFLAGS})
    326     set_target_link_flags(AsanNoinstTest ${ASAN_UNITTEST_NOINST_LINKFLAGS})
    327     target_link_libraries(AsanNoinstTest ${ASAN_UNITTEST_NOINST_LIBS})
    328 
    329     # Test with ASan instrumentation. Link with ASan dynamic runtime.
    330     add_executable(AsanTest
    331       ${COMPILER_RT_GTEST_SOURCE}
    332       ${ASAN_INST_TEST_SOURCES})
    333     set_target_compile_flags(AsanTest ${ASAN_UNITTEST_INSTRUMENTED_CFLAGS})
    334     set_target_link_flags(AsanTest ${ASAN_UNITTEST_INSTRUMENTED_LINKFLAGS})
    335     target_link_libraries(AsanTest ${ASAN_UNITTEST_INSTRUMENTED_LIBS})
    336 
    337     # Setup correct output directory and link flags.
    338     set_target_properties(AsanNoinstTest AsanTest PROPERTIES
    339       RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
    340     # Add unit tests to the test suite.
    341     add_dependencies(AsanUnitTests AsanNoinstTest AsanTest)
    342   endforeach()
    343 endif()
    344