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_TEST_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 append_if(COMPILER_RT_HAS_WNO_VARIADIC_MACROS_FLAG -Wno-variadic-macros ASAN_UNITTEST_COMMON_CFLAGS)
     35 
     36 # -gline-tables-only must be enough for ASan, so use it if possible.
     37 if(COMPILER_RT_TEST_COMPILER_ID MATCHES "Clang")
     38   list(APPEND ASAN_UNITTEST_COMMON_CFLAGS -gline-tables-only)
     39 else()
     40   list(APPEND ASAN_UNITTEST_COMMON_CFLAGS -g)
     41 endif()
     42 
     43 # Use -D instead of definitions to please custom compile command.
     44 list(APPEND ASAN_UNITTEST_COMMON_CFLAGS
     45   -DASAN_HAS_BLACKLIST=1
     46   -DASAN_HAS_EXCEPTIONS=1
     47   -DASAN_UAR=0)
     48 
     49 set(ASAN_BLACKLIST_FILE "${CMAKE_CURRENT_SOURCE_DIR}/asan_test.ignore")
     50 set(ASAN_UNITTEST_INSTRUMENTED_CFLAGS
     51   ${ASAN_UNITTEST_COMMON_CFLAGS}
     52   -fsanitize=address
     53   "-fsanitize-blacklist=${ASAN_BLACKLIST_FILE}"
     54   -mllvm -asan-instrument-assembly
     55 )
     56 
     57 if(NOT MSVC)
     58   list(APPEND ASAN_UNITTEST_COMMON_LINKFLAGS --driver-mode=g++)
     59 endif()
     60 
     61 # x86_64 FreeBSD 9.2 additionally requires libc++ to build the tests.
     62 if(CMAKE_SYSTEM MATCHES "FreeBSD-9.2-RELEASE")
     63   list(APPEND ASAN_UNITTEST_COMMON_LINKFLAGS "-lc++")
     64 endif()
     65 
     66 # Unit tests on Mac depend on Foundation.
     67 if(APPLE)
     68   list(APPEND ASAN_UNITTEST_COMMON_LINKFLAGS -framework Foundation)
     69 endif()
     70 if(ANDROID)
     71   list(APPEND ASAN_UNITTEST_COMMON_LINKFLAGS -pie)
     72 endif()
     73 
     74 set(ASAN_UNITTEST_INSTRUMENTED_LINKFLAGS
     75   ${ASAN_UNITTEST_COMMON_LINKFLAGS})
     76 # On Android, we link with ASan runtime manually. On other platforms we depend
     77 # on Clang driver behavior, passing -fsanitize=address flag.
     78 if(NOT ANDROID)
     79   list(APPEND ASAN_UNITTEST_INSTRUMENTED_LINKFLAGS -fsanitize=address)
     80 endif()
     81 
     82 set(ASAN_DYNAMIC_UNITTEST_INSTRUMENTED_LINKFLAGS
     83   ${ASAN_UNITTEST_INSTRUMENTED_LINKFLAGS}
     84   -shared-libasan)
     85 
     86 set(ASAN_UNITTEST_NOINST_LINKFLAGS ${ASAN_UNITTEST_COMMON_LINKFLAGS})
     87 append_if(COMPILER_RT_HAS_LIBM -lm ASAN_UNITTEST_NOINST_LINKFLAGS)
     88 append_if(COMPILER_RT_HAS_LIBDL -ldl ASAN_UNITTEST_NOINST_LINKFLAGS)
     89 append_if(COMPILER_RT_HAS_LIBPTHREAD -pthread ASAN_UNITTEST_NOINST_LINKFLAGS)
     90 append_if(COMPILER_RT_HAS_LIBPTHREAD -pthread
     91           ASAN_DYNAMIC_UNITTEST_INSTRUMENTED_LINKFLAGS)
     92 
     93 # Compile source for the given architecture, using compiler
     94 # options in ${ARGN}, and add it to the object list.
     95 macro(asan_compile obj_list source arch kind)
     96   get_filename_component(basename ${source} NAME)
     97   set(output_obj "${obj_list}.${basename}.${arch}${kind}.o")
     98   get_target_flags_for_arch(${arch} TARGET_CFLAGS)
     99   set(COMPILE_DEPS ${ASAN_UNITTEST_HEADERS} ${ASAN_BLACKLIST_FILE})
    100   if(NOT COMPILER_RT_STANDALONE_BUILD)
    101     list(APPEND COMPILE_DEPS gtest asan)
    102   endif()
    103   clang_compile(${output_obj} ${source}
    104                 CFLAGS ${ARGN} ${TARGET_CFLAGS}
    105                 DEPS ${COMPILE_DEPS})
    106   list(APPEND ${obj_list} ${output_obj})
    107 endmacro()
    108 
    109 # Link ASan unit test for a given architecture from a set
    110 # of objects in with given linker flags.
    111 macro(add_asan_test test_suite test_name arch kind)
    112   parse_arguments(TEST "OBJECTS;LINKFLAGS" "WITH_TEST_RUNTIME" ${ARGN})
    113   get_target_flags_for_arch(${arch} TARGET_LINK_FLAGS)
    114   set(TEST_DEPS ${TEST_OBJECTS})
    115   if(NOT COMPILER_RT_STANDALONE_BUILD)
    116     list(APPEND TEST_DEPS asan)
    117   endif()
    118   if(TEST_WITH_TEST_RUNTIME)
    119     list(APPEND TEST_DEPS ${ASAN_TEST_RUNTIME})
    120     if(NOT MSVC)
    121       list(APPEND TEST_OBJECTS lib${ASAN_TEST_RUNTIME}.a)
    122     else()
    123       list(APPEND TEST_OBJECTS ${ASAN_TEST_RUNTIME}.lib)
    124     endif()
    125   endif()
    126   add_compiler_rt_test(${test_suite} ${test_name}
    127                        OBJECTS ${TEST_OBJECTS}
    128                        DEPS ${TEST_DEPS}
    129                        LINK_FLAGS ${TEST_LINKFLAGS}
    130                                   ${TARGET_LINK_FLAGS})
    131 endmacro()
    132 
    133 # Main AddressSanitizer unit tests.
    134 add_custom_target(AsanUnitTests)
    135 set_target_properties(AsanUnitTests PROPERTIES FOLDER "ASan unit tests")
    136 # ASan benchmarks (not actively used now).
    137 add_custom_target(AsanBenchmarks)
    138 set_target_properties(AsanBenchmarks PROPERTIES FOLDER "Asan benchmarks")
    139 
    140 set(ASAN_NOINST_TEST_SOURCES
    141   ${COMPILER_RT_GTEST_SOURCE}
    142   asan_fake_stack_test.cc
    143   asan_noinst_test.cc
    144   asan_test_main.cc)
    145 
    146 set(ASAN_INST_TEST_SOURCES
    147   ${COMPILER_RT_GTEST_SOURCE}
    148   asan_asm_test.cc
    149   asan_globals_test.cc
    150   asan_interface_test.cc
    151   asan_test.cc
    152   asan_oob_test.cc
    153   asan_mem_test.cc
    154   asan_str_test.cc
    155   asan_test_main.cc)
    156 if(APPLE)
    157   list(APPEND ASAN_INST_TEST_SOURCES asan_mac_test.cc)
    158 endif()
    159 
    160 set(ASAN_BENCHMARKS_SOURCES
    161   ${COMPILER_RT_GTEST_SOURCE}
    162   asan_benchmarks_test.cc)
    163 
    164 # Adds ASan unit tests and benchmarks for architecture.
    165 macro(add_asan_tests_for_arch_and_kind arch kind)
    166   # Instrumented tests.
    167   set(ASAN_INST_TEST_OBJECTS)
    168   foreach(src ${ASAN_INST_TEST_SOURCES})
    169     asan_compile(ASAN_INST_TEST_OBJECTS ${src} ${arch} ${kind}
    170       ${ASAN_UNITTEST_INSTRUMENTED_CFLAGS} ${ARGN})
    171   endforeach()
    172   if (APPLE)
    173     # Add Mac-specific helper.
    174     asan_compile(ASAN_INST_TEST_OBJECTS asan_mac_test_helpers.mm ${arch} ${kind}
    175                  ${ASAN_UNITTEST_INSTRUMENTED_CFLAGS} -ObjC ${ARGN})
    176   endif()
    177   add_asan_test(AsanUnitTests "Asan-${arch}${kind}-Test" ${arch} ${kind}
    178                 OBJECTS ${ASAN_INST_TEST_OBJECTS}
    179                 LINKFLAGS ${ASAN_UNITTEST_INSTRUMENTED_LINKFLAGS})
    180   if(COMPILER_RT_BUILD_SHARED_ASAN)
    181     add_asan_test(AsanUnitTests "Asan-${arch}${kind}-Dynamic-Test" ${arch} ${kind}
    182                   OBJECTS ${ASAN_INST_TEST_OBJECTS}
    183                   LINKFLAGS ${ASAN_DYNAMIC_UNITTEST_INSTRUMENTED_LINKFLAGS})
    184   endif()
    185 
    186   # Add static ASan runtime that will be linked with uninstrumented tests.
    187   set(ASAN_TEST_RUNTIME RTAsanTest.${arch}${kind})
    188   if(APPLE)
    189     set(ASAN_TEST_RUNTIME_OBJECTS
    190       $<TARGET_OBJECTS:RTAsan.osx>
    191       $<TARGET_OBJECTS:RTInterception.osx>
    192       $<TARGET_OBJECTS:RTSanitizerCommon.osx>
    193       $<TARGET_OBJECTS:RTLSanCommon.osx>)
    194   else()
    195     set(ASAN_TEST_RUNTIME_OBJECTS
    196       $<TARGET_OBJECTS:RTAsan.${arch}>
    197       $<TARGET_OBJECTS:RTAsan_cxx.${arch}>
    198       $<TARGET_OBJECTS:RTInterception.${arch}>
    199       $<TARGET_OBJECTS:RTSanitizerCommon.${arch}>
    200       $<TARGET_OBJECTS:RTSanitizerCommonLibc.${arch}>)
    201     if(NOT MSVC)
    202       list(APPEND ASAN_TEST_RUNTIME_OBJECTS
    203            $<TARGET_OBJECTS:RTLSanCommon.${arch}>)
    204     endif()
    205   endif()
    206   add_library(${ASAN_TEST_RUNTIME} STATIC ${ASAN_TEST_RUNTIME_OBJECTS})
    207   set_target_properties(${ASAN_TEST_RUNTIME} PROPERTIES
    208     ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
    209   # Uninstrumented tests.
    210   set(ASAN_NOINST_TEST_OBJECTS)
    211   foreach(src ${ASAN_NOINST_TEST_SOURCES})
    212     asan_compile(ASAN_NOINST_TEST_OBJECTS ${src} ${arch} ${kind}
    213                  ${ASAN_UNITTEST_COMMON_CFLAGS} ${ARGN})
    214   endforeach()
    215   add_asan_test(AsanUnitTests "Asan-${arch}${kind}-Noinst-Test" ${arch} ${kind}
    216                 OBJECTS ${ASAN_NOINST_TEST_OBJECTS}
    217                 LINKFLAGS ${ASAN_UNITTEST_NOINST_LINKFLAGS}
    218                 WITH_TEST_RUNTIME)
    219 
    220   # Benchmarks.
    221   set(ASAN_BENCHMARKS_OBJECTS)
    222   foreach(src ${ASAN_BENCHMARKS_SOURCES})
    223     asan_compile(ASAN_BENCHMARKS_OBJECTS ${src} ${arch} ${kind}
    224                  ${ASAN_UNITTEST_INSTRUMENTED_CFLAGS} ${ARGN})
    225   endforeach()
    226   add_asan_test(AsanBenchmarks "Asan-${arch}${kind}-Benchmark" ${arch} ${kind}
    227                 OBJECTS ${ASAN_BENCHMARKS_OBJECTS}
    228                 LINKFLAGS ${ASAN_UNITTEST_INSTRUMENTED_LINKFLAGS})
    229   if(COMPILER_RT_BUILD_SHARED_ASAN)
    230     add_asan_test(AsanBenchmarks "Asan-${arch}${kind}-Dynamic-Benchmark" ${arch} ${kind}
    231                   OBJECTS ${ASAN_BENCHMARKS_OBJECTS}
    232                   LINKFLAGS ${ASAN_DYNAMIC_UNITTEST_INSTRUMENTED_LINKFLAGS})
    233   endif()
    234 endmacro()
    235 
    236 if(COMPILER_RT_CAN_EXECUTE_TESTS)
    237   foreach(arch ${ASAN_SUPPORTED_ARCH})
    238     add_asan_tests_for_arch_and_kind(${arch} "-inline")
    239     add_asan_tests_for_arch_and_kind(${arch} "-with-calls"
    240       -mllvm -asan-instrumentation-with-call-threshold=0)
    241   endforeach()
    242 endif()
    243 
    244 if(ANDROID)
    245   # We assume that unit tests on Android are built in a build
    246   # tree with fresh Clang as a host compiler.
    247   
    248   # Test w/o ASan instrumentation. Link it with ASan statically.
    249   add_executable(AsanNoinstTest
    250     $<TARGET_OBJECTS:RTAsan.arm.android>
    251     $<TARGET_OBJECTS:RTInterception.arm.android>
    252     $<TARGET_OBJECTS:RTSanitizerCommon.arm.android>
    253     ${COMPILER_RT_GTEST_SOURCE}
    254     ${ASAN_NOINST_TEST_SOURCES})
    255   set_target_compile_flags(AsanNoinstTest ${ASAN_UNITTEST_COMMON_CFLAGS})
    256   set_target_link_flags(AsanNoinstTest ${ASAN_UNITTEST_NOINST_LINKFLAGS})
    257   target_link_libraries(AsanNoinstTest log)
    258 
    259   # Test with ASan instrumentation. Link with ASan dynamic runtime.
    260   add_executable(AsanTest
    261     ${COMPILER_RT_GTEST_SOURCE}
    262     ${ASAN_INST_TEST_SOURCES})
    263   set_target_compile_flags(AsanTest ${ASAN_UNITTEST_INSTRUMENTED_CFLAGS})
    264   set_target_link_flags(AsanTest ${ASAN_UNITTEST_INSTRUMENTED_LINKFLAGS})
    265   target_link_libraries(AsanTest clang_rt.asan-arm-android)
    266 
    267   # Setup correct output directory and link flags.
    268   set_target_properties(AsanNoinstTest AsanTest PROPERTIES
    269     RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
    270   # Add unit test to test suite.
    271   add_dependencies(AsanUnitTests AsanNoinstTest AsanTest)
    272 endif()
    273