aboutsummaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
Diffstat (limited to 'test')
-rw-r--r--test/CMakeLists.txt6
-rw-r--r--test/asan/CMakeLists.txt28
-rw-r--r--test/asan/TestCases/Darwin/asan_gen_prefixes.cc10
-rw-r--r--test/asan/TestCases/Darwin/odr-lto.cc12
-rw-r--r--test/asan/TestCases/Linux/activation-options.cc1
-rw-r--r--test/asan/TestCases/Linux/allocator_oom_test.cc4
-rw-r--r--test/asan/TestCases/Linux/clang_gcc_abi.cc3
-rw-r--r--test/asan/TestCases/Linux/clone_test.cc1
-rw-r--r--test/asan/TestCases/Linux/coverage-missing.cc24
-rw-r--r--test/asan/TestCases/Linux/interception_readdir_r_test.cc19
-rw-r--r--test/asan/TestCases/Linux/local_alias.cc4
-rw-r--r--test/asan/TestCases/Linux/long-object-path.cc7
-rw-r--r--test/asan/TestCases/Linux/odr-violation.cc4
-rw-r--r--test/asan/TestCases/Linux/pvalloc-overflow.cc41
-rw-r--r--test/asan/TestCases/Linux/quarantine_size_mb.cc4
-rw-r--r--test/asan/TestCases/Linux/stack-trace-dlclose.cc6
-rw-r--r--test/asan/TestCases/Linux/syscalls.cc3
-rw-r--r--test/asan/TestCases/Posix/asan-sigbus.cpp6
-rw-r--r--test/asan/TestCases/Posix/asan-symbolize-bad-path.cc2
-rw-r--r--test/asan/TestCases/Posix/concurrent_overflow.cc7
-rw-r--r--test/asan/TestCases/Posix/coverage-fork.cc4
-rw-r--r--test/asan/TestCases/Posix/coverage-reset.cc2
-rw-r--r--test/asan/TestCases/Posix/coverage.cc4
-rw-r--r--test/asan/TestCases/Posix/fgets_fputs.cc54
-rw-r--r--test/asan/TestCases/Posix/fread_fwrite.cc3
-rw-r--r--test/asan/TestCases/Posix/glob.cc1
-rw-r--r--test/asan/TestCases/Posix/invalid-pointer-pairs-threads.cc4
-rw-r--r--test/asan/TestCases/Posix/ioctl.cc4
-rw-r--r--test/asan/TestCases/Posix/lto-constmerge-odr.cc14
-rw-r--r--test/asan/TestCases/Posix/mmap_limit_mb.cc2
-rw-r--r--test/asan/TestCases/Posix/no_asan_gen_globals.c6
-rw-r--r--test/asan/TestCases/Posix/shared-lib-test.cc1
-rw-r--r--test/asan/TestCases/Posix/stack-use-after-return.cc8
-rw-r--r--test/asan/TestCases/Posix/start-deactivated.cc1
-rw-r--r--test/asan/TestCases/Posix/strndup_oob_test.cc2
-rw-r--r--test/asan/TestCases/Posix/strndup_oob_test2.cc4
-rw-r--r--test/asan/TestCases/Windows/coverage-basic.cc4
-rw-r--r--test/asan/TestCases/Windows/fuse-lld-globals.cc18
-rw-r--r--test/asan/TestCases/Windows/oom.cc2
-rw-r--r--test/asan/TestCases/Windows/user-exception.cc36
-rw-r--r--test/asan/TestCases/alloca_constant_size.cc7
-rw-r--r--test/asan/TestCases/alloca_loop_unpoisoning.cc4
-rw-r--r--test/asan/TestCases/alloca_vla_interact.cc4
-rw-r--r--test/asan/TestCases/allocator_returns_null.cc131
-rw-r--r--test/asan/TestCases/calloc-overflow.cc21
-rw-r--r--test/asan/TestCases/coverage-and-lsan.cc8
-rw-r--r--test/asan/TestCases/coverage-disabled.cc10
-rw-r--r--test/asan/TestCases/debug_double_free.cc3
-rw-r--r--test/asan/TestCases/debug_ppc64_mapping.cc18
-rw-r--r--test/asan/TestCases/debug_report.cc3
-rw-r--r--test/asan/TestCases/handle_noreturn_bug.cc13
-rw-r--r--test/asan/TestCases/heavy_uar_test.cc6
-rw-r--r--test/asan/TestCases/intercept-rethrow-exception.cc64
-rw-r--r--test/asan/TestCases/invalid-pointer-pairs-compare-errors.cc6
-rw-r--r--test/asan/TestCases/invalid-pointer-pairs-compare-null.cc42
-rw-r--r--test/asan/TestCases/invalid-pointer-pairs-compare-success.cc2
-rw-r--r--test/asan/TestCases/invalid-pointer-pairs-subtract-errors.cc2
-rw-r--r--test/asan/TestCases/invalid-pointer-pairs-subtract-success.cc4
-rw-r--r--test/asan/TestCases/malloc-no-intercept.c5
-rw-r--r--test/asan/TestCases/malloc-size-too-big.cc28
-rw-r--r--test/asan/TestCases/non-executable-pc.cpp11
-rw-r--r--test/asan/TestCases/null_deref.cc4
-rw-r--r--test/asan/TestCases/printf-4.c5
-rw-r--r--test/asan/TestCases/scariness_score_test.cc2
-rw-r--r--test/asan/TestCases/strcat-overlap.cc54
-rw-r--r--test/asan/TestCases/strcpy-overlap.cc48
-rw-r--r--test/asan/TestCases/strdup_oob_test.cc2
-rw-r--r--test/asan/TestCases/strncat-overlap.cc48
-rw-r--r--test/asan/TestCases/strncpy-overlap.cc48
-rw-r--r--test/asan/TestCases/suppressions-exec-relative-location.cc12
-rw-r--r--test/asan/TestCases/suppressions-library.cc2
-rw-r--r--test/asan/TestCases/throw_invoke_test.cc2
-rw-r--r--test/asan/TestCases/verbose-log-path_test.cc9
-rw-r--r--test/asan/lit.cfg18
-rw-r--r--test/asan/lit.site.cfg.in3
-rw-r--r--test/builtins/CMakeLists.txt5
-rw-r--r--test/builtins/TestCases/Darwin/os_version_check_test.c2
-rw-r--r--test/builtins/TestCases/Darwin/os_version_check_test_no_core_foundation.c2
-rw-r--r--test/builtins/Unit/lit.cfg8
-rw-r--r--test/builtins/Unit/riscv/mulsi3_test.c119
-rw-r--r--test/cfi/CMakeLists.txt22
-rw-r--r--test/cfi/create-derivers.test6
-rw-r--r--test/cfi/cross-dso-diagnostic.cpp47
-rw-r--r--test/cfi/cross-dso/icall/dlopen.cpp6
-rw-r--r--test/cfi/lit.site.cfg.in1
-rw-r--r--test/cfi/mfcall.cpp96
-rw-r--r--test/cfi/simple-pass.cpp5
-rw-r--r--test/cfi/target_uninstrumented.cpp6
-rw-r--r--test/dfsan/custom.cc2
-rw-r--r--test/dfsan/trace-cmp.c50
-rw-r--r--test/fuzzer/AbsNegAndConstant64Test.cpp3
-rw-r--r--test/fuzzer/AbsNegAndConstantTest.cpp3
-rw-r--r--test/fuzzer/AcquireCrashStateTest.cpp18
-rw-r--r--test/fuzzer/Bingo.h1
-rw-r--r--test/fuzzer/CMakeLists.txt108
-rw-r--r--test/fuzzer/CleanseTest.cpp2
-rw-r--r--test/fuzzer/ExplodeDFSanLabelsTest.cpp23
-rw-r--r--test/fuzzer/LeakTest.cpp2
-rw-r--r--test/fuzzer/MultipleConstraintsOnSmallInputTest.cpp4129
-rw-r--r--test/fuzzer/NullDerefTest.cpp4
-rw-r--r--test/fuzzer/OnlySomeBytesTest.cpp40
-rw-r--r--test/fuzzer/PrintUnstableStatsTest.cpp69
-rw-r--r--test/fuzzer/ShrinkValueProfileTest.cpp2
-rw-r--r--test/fuzzer/SimpleCmpTest.cpp6
-rw-r--r--test/fuzzer/SimpleTestStdio.cpp26
-rw-r--r--test/fuzzer/SwapCmpTest.cpp6
-rw-r--r--test/fuzzer/SymbolizeDeadlock.cpp35
-rw-r--r--test/fuzzer/ThreadedLeakTest.cpp2
-rw-r--r--test/fuzzer/ThreeBytes.cpp14
-rw-r--r--test/fuzzer/ThreeFunctionsTest.cpp36
-rw-r--r--test/fuzzer/TraceMallocThreadedTest.cpp3
-rw-r--r--test/fuzzer/UninitializedStrlen.cpp14
-rw-r--r--test/fuzzer/UseAfterDtor.cpp27
-rw-r--r--test/fuzzer/acquire-crash-state.test3
-rw-r--r--test/fuzzer/afl-driver-extra-stats.test5
-rw-r--r--test/fuzzer/afl-driver-stderr.test10
-rw-r--r--test/fuzzer/afl-driver.test12
-rw-r--r--test/fuzzer/bad-strcmp.test2
-rw-r--r--test/fuzzer/bogus-initialize.test4
-rw-r--r--test/fuzzer/buffer-overflow-on-input.test5
-rw-r--r--test/fuzzer/caller-callee.test3
-rw-r--r--test/fuzzer/cleanse.test2
-rw-r--r--test/fuzzer/counters.test9
-rw-r--r--test/fuzzer/coverage.test29
-rw-r--r--test/fuzzer/cxxstring.test4
-rw-r--r--test/fuzzer/dataflow.test84
-rw-r--r--test/fuzzer/deep-recursion.test2
-rw-r--r--test/fuzzer/disable-leaks.test3
-rw-r--r--test/fuzzer/dso.test7
-rw-r--r--test/fuzzer/dump_coverage.test17
-rw-r--r--test/fuzzer/equivalence-signals.test9
-rw-r--r--test/fuzzer/equivalence.test6
-rw-r--r--test/fuzzer/exit-report.test2
-rw-r--r--test/fuzzer/exit_on_src_pos.test9
-rw-r--r--test/fuzzer/extra-counters.test4
-rw-r--r--test/fuzzer/fprofile-instr-generate.test7
-rw-r--r--test/fuzzer/full-coverage-set.test3
-rw-r--r--test/fuzzer/fuzzer-customcrossover.test4
-rw-r--r--test/fuzzer/fuzzer-customcrossoverandmutate.test2
-rw-r--r--test/fuzzer/fuzzer-custommutator.test2
-rw-r--r--test/fuzzer/fuzzer-dict.test4
-rw-r--r--test/fuzzer/fuzzer-dirs.test8
-rw-r--r--test/fuzzer/fuzzer-fdmask.test34
-rw-r--r--test/fuzzer/fuzzer-finalstats.test4
-rw-r--r--test/fuzzer/fuzzer-flags.test10
-rw-r--r--test/fuzzer/fuzzer-leak.test23
-rw-r--r--test/fuzzer/fuzzer-mutationstats.test5
-rw-r--r--test/fuzzer/fuzzer-oom-with-profile.test2
-rw-r--r--test/fuzzer/fuzzer-oom.test11
-rw-r--r--test/fuzzer/fuzzer-printcovpcs.test4
-rw-r--r--test/fuzzer/fuzzer-runs.test6
-rw-r--r--test/fuzzer/fuzzer-seed.test2
-rw-r--r--test/fuzzer/fuzzer-segv.test4
-rw-r--r--test/fuzzer/fuzzer-singleinputs.test6
-rw-r--r--test/fuzzer/fuzzer-threaded.test8
-rw-r--r--test/fuzzer/fuzzer-timeout.test8
-rw-r--r--test/fuzzer/fuzzer-ubsan.test2
-rw-r--r--test/fuzzer/fuzzer.test70
-rw-r--r--test/fuzzer/gc-sections.test10
-rw-r--r--test/fuzzer/handle-unstable.test42
-rw-r--r--test/fuzzer/initialize.test3
-rw-r--r--test/fuzzer/inline-8bit-counters.test4
-rw-r--r--test/fuzzer/lit.cfg58
-rw-r--r--test/fuzzer/lit.site.cfg.in11
-rw-r--r--test/fuzzer/max-number-of-runs.test6
-rw-r--r--test/fuzzer/memcmp.test3
-rw-r--r--test/fuzzer/memcmp64.test3
-rw-r--r--test/fuzzer/merge-control-file.test15
-rw-r--r--test/fuzzer/merge-posix.test5
-rw-r--r--test/fuzzer/merge-sigusr.test3
-rw-r--r--test/fuzzer/merge-summary.test4
-rw-r--r--test/fuzzer/merge.test17
-rw-r--r--test/fuzzer/minimize_crash.test23
-rw-r--r--test/fuzzer/minimize_two_crashes.test8
-rw-r--r--test/fuzzer/msan.test24
-rw-r--r--test/fuzzer/not-instrumented.test4
-rw-r--r--test/fuzzer/null-deref-on-empty.test4
-rw-r--r--test/fuzzer/null-deref.test10
-rw-r--r--test/fuzzer/only-some-bytes.test38
-rw-r--r--test/fuzzer/overwrite-input.test2
-rw-r--r--test/fuzzer/print-func.test5
-rw-r--r--test/fuzzer/print_unstable_stats.test3
-rw-r--r--test/fuzzer/recommended-dictionary.test3
-rw-r--r--test/fuzzer/reduce_inputs.test6
-rw-r--r--test/fuzzer/repeated-bytes.test2
-rw-r--r--test/fuzzer/shrink.test6
-rw-r--r--test/fuzzer/sigusr.test3
-rw-r--r--test/fuzzer/simple-cmp.test6
-rw-r--r--test/fuzzer/simple.test7
-rw-r--r--test/fuzzer/standalone.test2
-rw-r--r--test/fuzzer/strcmp.test3
-rw-r--r--test/fuzzer/strncmp-oob.test6
-rw-r--r--test/fuzzer/strncmp.test3
-rw-r--r--test/fuzzer/strstr.test3
-rw-r--r--test/fuzzer/swap-cmp.test2
-rw-r--r--test/fuzzer/symbolize-deadlock.test2
-rw-r--r--test/fuzzer/target-function.test30
-rw-r--r--test/fuzzer/three-bytes.test8
-rw-r--r--test/fuzzer/trace-malloc-2.test2
-rw-r--r--test/fuzzer/trace-malloc-threaded.test7
-rw-r--r--test/fuzzer/trace-malloc-unbalanced.test4
-rw-r--r--test/fuzzer/trace-malloc.test2
-rw-r--r--test/fuzzer/trace-pc.test4
-rw-r--r--test/fuzzer/ulimit.test2
-rw-r--r--test/fuzzer/value-profile-cmp.test2
-rw-r--r--test/fuzzer/value-profile-cmp2.test2
-rw-r--r--test/fuzzer/value-profile-cmp3.test2
-rw-r--r--test/fuzzer/value-profile-cmp4.test2
-rw-r--r--test/fuzzer/value-profile-div.test4
-rw-r--r--test/fuzzer/value-profile-load.test4
-rw-r--r--test/fuzzer/value-profile-mem.test3
-rw-r--r--test/fuzzer/value-profile-set.test2
-rw-r--r--test/fuzzer/value-profile-strcmp.test3
-rw-r--r--test/fuzzer/value-profile-strncmp.test3
-rw-r--r--test/fuzzer/value-profile-switch.test5
-rw-r--r--test/hwasan/TestCases/Linux/aligned_alloc-alignment.cc25
-rw-r--r--test/hwasan/TestCases/Linux/lit.local.cfg9
-rw-r--r--test/hwasan/TestCases/Linux/pvalloc-overflow.cc46
-rw-r--r--test/hwasan/TestCases/Posix/lit.local.cfg9
-rw-r--r--test/hwasan/TestCases/Posix/posix_memalign-alignment.cc22
-rw-r--r--test/hwasan/TestCases/allocator_returns_null.cc (renamed from test/msan/allocator_returns_null.cc)87
-rw-r--r--test/hwasan/TestCases/check-interface.cc22
-rw-r--r--test/hwasan/TestCases/stack-oob.cc25
-rw-r--r--test/hwasan/TestCases/stack-uar.cc23
-rw-r--r--test/hwasan/TestCases/use-after-free.c39
-rw-r--r--test/hwasan/TestCases/use-after-free.cc39
-rw-r--r--test/hwasan/lit.cfg4
-rw-r--r--test/lit.common.cfg118
-rw-r--r--test/lit.common.configured.in10
-rw-r--r--test/lsan/TestCases/Linux/fork_with_threads.cc35
-rw-r--r--test/lsan/TestCases/Linux/log-path_test.cc26
-rw-r--r--test/lsan/TestCases/Linux/use_tls_dynamic.cc2
-rw-r--r--test/lsan/TestCases/Posix/lit.local.cfg9
-rw-r--r--test/lsan/TestCases/allocator_returns_null.cc131
-rw-r--r--test/msan/Linux/name_to_handle_at.cc28
-rw-r--r--test/msan/Linux/sendmsg.cc137
-rw-r--r--test/msan/check-handler.cc16
-rw-r--r--test/msan/coverage-levels.cc10
-rw-r--r--test/msan/dtls_test.c3
-rw-r--r--test/msan/dtor-member.cc2
-rw-r--r--test/msan/fgets_fputs.cc47
-rw-r--r--test/msan/fstat.cc15
-rw-r--r--test/msan/getutent.cc4
-rw-r--r--test/msan/iconv.cc2
-rw-r--r--test/msan/lit.cfg2
-rw-r--r--test/msan/mmap.cc6
-rw-r--r--test/msan/pthread_getattr_np_deadlock.cc10
-rw-r--r--test/msan/pthread_getname_np.cc16
-rw-r--r--test/msan/pvalloc.cc43
-rw-r--r--test/msan/scoped-interceptors.cc52
-rw-r--r--test/msan/strlen_of_shadow.cc2
-rw-r--r--test/msan/textdomain.cc2
-rw-r--r--test/msan/tls_reuse.cc1
-rw-r--r--test/msan/tsearch.cc2
-rw-r--r--test/msan/tzset.cc1
-rw-r--r--test/msan/use-after-dtor.cc19
-rw-r--r--test/msan/vector_div.cc17
-rw-r--r--test/msan/wcsxfrm.cc30
-rw-r--r--test/profile/Inputs/instrprof-dlopen-dlclose-main.c86
-rw-r--r--test/profile/Inputs/instrprof-dlopen-dlclose-main.c.gcov91
-rw-r--r--test/profile/Inputs/instrprof-dlopen-dlclose-main_three-libs.c.gcov91
-rw-r--r--test/profile/Inputs/instrprof-dlopen-func.c2
-rw-r--r--test/profile/Inputs/instrprof-dlopen-func.c.gcov6
-rw-r--r--test/profile/Inputs/instrprof-dlopen-func2.c2
-rw-r--r--test/profile/Inputs/instrprof-dlopen-func2.c.gcov6
-rw-r--r--test/profile/Inputs/instrprof-dlopen-func3.c1
-rw-r--r--test/profile/Inputs/instrprof-dlopen-func3.c.gcov6
-rw-r--r--test/profile/Inputs/instrprof-gcov-__gcov_flush-terminate.c13
-rw-r--r--test/profile/Inputs/instrprof-gcov-__gcov_flush-terminate.c.gcov18
-rw-r--r--test/profile/Inputs/instrprof-gcov-exceptions.cpp11
-rw-r--r--test/profile/Inputs/instrprof-gcov-exceptions.cpp.gcov16
-rw-r--r--test/profile/Inputs/instrprof-gcov-multiple-bbs-single-line.c20
-rw-r--r--test/profile/Inputs/instrprof-gcov-multiple-bbs-single-line.c.gcov34
-rw-r--r--test/profile/Inputs/instrprof-shared-lib.c.gcov14
-rw-r--r--test/profile/Inputs/instrprof-shared-lib_called-twice.c.gcov14
-rw-r--r--test/profile/Inputs/instrprof-shared-lib_in-loop.c.gcov14
-rw-r--r--test/profile/Inputs/instrprof-shared-main-gcov-flush.c36
-rw-r--r--test/profile/Inputs/instrprof-shared-main-gcov-flush_no-writeout.c.gcov41
-rw-r--r--test/profile/Inputs/instrprof-shared-main-gcov-flush_shared-call-after.c.gcov41
-rw-r--r--test/profile/Inputs/instrprof-shared-main-gcov-flush_shared-call-before-after.c.gcov41
-rw-r--r--test/profile/Inputs/instrprof-shared-main-gcov-flush_shared-call-before.c.gcov41
-rw-r--r--test/profile/Inputs/instrprof-shared-main.c.gcov18
-rw-r--r--test/profile/Linux/counter_promo_nest.c3
-rw-r--r--test/profile/Linux/instrprof-value-merge.c79
-rw-r--r--test/profile/instrprof-darwin-dead-strip.c16
-rw-r--r--test/profile/instrprof-darwin-exports.c11
-rw-r--r--test/profile/instrprof-dlopen-dlclose-gcov.test30
-rw-r--r--test/profile/instrprof-gcov-__gcov_flush-terminate.test12
-rw-r--r--test/profile/instrprof-gcov-exceptions.test21
-rw-r--r--test/profile/instrprof-gcov-multiple-bbs-single-line.test13
-rw-r--r--test/profile/instrprof-gcov-two-objects.test18
-rw-r--r--test/profile/instrprof-get-filename.c39
-rw-r--r--test/profile/instrprof-path.c2
-rw-r--r--test/profile/instrprof-reset-counters.c2
-rw-r--r--test/profile/instrprof-shared-gcov-flush.test52
-rw-r--r--test/profile/instrprof-visibility.cpp4
-rw-r--r--test/sanitizer_common/CMakeLists.txt8
-rw-r--r--test/sanitizer_common/TestCases/Linux/aligned_alloc-alignment.cc43
-rw-r--r--test/sanitizer_common/TestCases/Linux/hard_rss_limit_mb_test.cc3
-rw-r--r--test/sanitizer_common/TestCases/Linux/mmap64_test.c13
-rw-r--r--test/sanitizer_common/TestCases/Linux/mmap_write_exec.cpp37
-rw-r--r--test/sanitizer_common/TestCases/Linux/name_to_handle_at.cc21
-rw-r--r--test/sanitizer_common/TestCases/Linux/pthread_mutex.cc34
-rw-r--r--test/sanitizer_common/TestCases/Linux/pvalloc-overflow.cc47
-rw-r--r--test/sanitizer_common/TestCases/Linux/soft_rss_limit_mb_test.cc6
-rw-r--r--test/sanitizer_common/TestCases/Linux/sysconf_interceptor_bypass_test.cc8
-rw-r--r--test/sanitizer_common/TestCases/NetBSD/faccessat.cc6
-rw-r--r--test/sanitizer_common/TestCases/NetBSD/getgrouplist.cc29
-rw-r--r--test/sanitizer_common/TestCases/NetBSD/getgroupmembership.cc30
-rw-r--r--test/sanitizer_common/TestCases/NetBSD/gid_from_group.cc16
-rw-r--r--test/sanitizer_common/TestCases/NetBSD/group_from_gid.cc17
-rw-r--r--test/sanitizer_common/TestCases/NetBSD/lit.local.cfg9
-rw-r--r--test/sanitizer_common/TestCases/NetBSD/netent.cc84
-rw-r--r--test/sanitizer_common/TestCases/NetBSD/paccept.cc74
-rw-r--r--test/sanitizer_common/TestCases/NetBSD/protoent.cc89
-rw-r--r--test/sanitizer_common/TestCases/NetBSD/strmode.cc20
-rw-r--r--test/sanitizer_common/TestCases/NetBSD/ttyent.cc70
-rw-r--r--test/sanitizer_common/TestCases/NetBSD/uid_from_user.cc16
-rw-r--r--test/sanitizer_common/TestCases/NetBSD/user_from_uid.cc17
-rw-r--r--test/sanitizer_common/TestCases/Posix/access.cc5
-rw-r--r--test/sanitizer_common/TestCases/Posix/devname.cc23
-rw-r--r--test/sanitizer_common/TestCases/Posix/devname_r.cc28
-rw-r--r--test/sanitizer_common/TestCases/Posix/fgetln.cc24
-rw-r--r--test/sanitizer_common/TestCases/Posix/fgets.cc20
-rw-r--r--test/sanitizer_common/TestCases/Posix/fputs_puts.cc18
-rw-r--r--test/sanitizer_common/TestCases/Posix/getpass.cc8
-rw-r--r--test/sanitizer_common/TestCases/Posix/illegal_read_test.cc15
-rw-r--r--test/sanitizer_common/TestCases/Posix/illegal_write_test.cc14
-rw-r--r--test/sanitizer_common/TestCases/Posix/lstat.cc16
-rw-r--r--test/sanitizer_common/TestCases/Posix/mmap_test.c11
-rw-r--r--test/sanitizer_common/TestCases/Posix/posix_memalign-alignment.cc47
-rw-r--r--test/sanitizer_common/TestCases/Posix/readlink.c26
-rw-r--r--test/sanitizer_common/TestCases/Posix/readlinkat.c26
-rw-r--r--test/sanitizer_common/TestCases/Posix/sanitizer_set_death_callback_test.cc11
-rw-r--r--test/sanitizer_common/TestCases/Posix/strlcat.cc54
-rw-r--r--test/sanitizer_common/TestCases/Posix/strlcpy.cc54
-rw-r--r--test/sanitizer_common/TestCases/Posix/strxfrm.c20
-rw-r--r--test/sanitizer_common/TestCases/Posix/wcsxfrm.c20
-rw-r--r--test/sanitizer_common/TestCases/allocator_returns_null.cc114
-rw-r--r--test/sanitizer_common/TestCases/ctype.c89
-rw-r--r--test/sanitizer_common/TestCases/get_module_and_offset_for_pc.cc5
-rwxr-xr-xtest/sanitizer_common/ios_commands/iossim_prepare.py5
-rw-r--r--test/sanitizer_common/lit.common.cfg5
-rw-r--r--test/scudo/aligned-new.cpp86
-rw-r--r--test/scudo/alignment.c2
-rw-r--r--test/scudo/double-free.cpp8
-rw-r--r--test/scudo/fsanitize.c28
-rw-r--r--test/scudo/interface.cpp15
-rw-r--r--test/scudo/lit.cfg23
-rw-r--r--test/scudo/memalign.c28
-rw-r--r--test/scudo/mismatch.cpp24
-rw-r--r--test/scudo/preload.cpp3
-rw-r--r--test/scudo/random_shuffle.cpp16
-rw-r--r--test/scudo/realloc.cpp10
-rw-r--r--test/scudo/sized-delete.cpp2
-rw-r--r--test/scudo/sizes.cpp32
-rw-r--r--test/scudo/stats.c21
-rw-r--r--test/scudo/symbols.test8
-rw-r--r--test/scudo/valloc.c5
-rw-r--r--test/shadowcallstack/CMakeLists.txt21
-rw-r--r--test/shadowcallstack/init.c12
-rw-r--r--test/shadowcallstack/libc_support.h41
-rw-r--r--test/shadowcallstack/lit.cfg23
-rw-r--r--test/shadowcallstack/lit.site.cfg.in12
-rw-r--r--test/shadowcallstack/minimal_runtime.h43
-rw-r--r--test/shadowcallstack/overflow-aarch64.c5
-rw-r--r--test/shadowcallstack/overflow-x86_64.c5
-rw-r--r--test/shadowcallstack/overflow.c39
-rw-r--r--test/tsan/CMakeLists.txt17
-rw-r--r--test/tsan/Darwin/external-swift-debugging.cc68
-rw-r--r--test/tsan/Darwin/gcd-after-null.mm23
-rw-r--r--test/tsan/Darwin/norace-objcxx-run-time.mm2
-rw-r--r--test/tsan/Darwin/objc-synchronize-tagged.mm62
-rw-r--r--test/tsan/Darwin/objc-synchronize.mm57
-rw-r--r--test/tsan/allocator_returns_null.cc124
-rw-r--r--test/tsan/global_race.cc9
-rw-r--r--test/tsan/ignore_lib0.cc11
-rw-r--r--test/tsan/ignore_lib1.cc11
-rw-r--r--test/tsan/ignore_lib2.cc11
-rw-r--r--test/tsan/ignore_lib3.cc9
-rw-r--r--test/tsan/ignore_lib4.cc11
-rw-r--r--test/tsan/ignore_lib5.cc11
-rw-r--r--test/tsan/ignored-interceptors-mmap.cc1
-rw-r--r--test/tsan/java_symbolization.cc18
-rw-r--r--test/tsan/java_symbolization_legacy.cc44
-rw-r--r--test/tsan/lit.cfg9
-rw-r--r--test/tsan/lit.site.cfg.in3
-rw-r--r--test/tsan/mutex_destroy_locked2.cc29
-rw-r--r--test/tsan/race_on_fputs.cc29
-rw-r--r--test/tsan/simple_stack2.cc14
-rw-r--r--test/tsan/static_init6.cc3
-rw-r--r--test/tsan/strerror_r.cc18
-rw-r--r--test/tsan/suppressions_mutex.cc19
-rw-r--r--test/tsan/suppressions_mutex.cc.supp2
-rw-r--r--test/tsan/test.h2
-rw-r--r--test/tsan/thread_name.cc2
-rw-r--r--test/tsan/tls_race2.cc3
-rw-r--r--test/ubsan/CMakeLists.txt3
-rw-r--r--test/ubsan/TestCases/Float/cast-overflow.cpp10
-rw-r--r--test/ubsan/TestCases/Integer/negate-overflow.cpp4
-rw-r--r--test/ubsan/TestCases/Integer/no-recover.cpp2
-rw-r--r--test/ubsan/TestCases/Integer/suppressions.cpp2
-rw-r--r--test/ubsan/TestCases/Misc/coverage-levels.cc16
-rw-r--r--test/ubsan/TestCases/Misc/missing_return.cpp2
-rw-r--r--test/ubsan/TestCases/Misc/monitor.cpp44
-rw-r--r--test/ubsan/TestCases/TypeCheck/Function/function.cpp44
-rw-r--r--test/ubsan/TestCases/TypeCheck/misaligned.cpp2
-rw-r--r--test/ubsan/TestCases/TypeCheck/vptr.cpp2
-rw-r--r--test/ubsan/lit.common.cfg2
-rw-r--r--test/ubsan_minimal/CMakeLists.txt3
-rw-r--r--test/ubsan_minimal/lit.common.cfg2
-rw-r--r--test/xray/CMakeLists.txt12
-rw-r--r--test/xray/TestCases/Posix/always-never-instrument.cc (renamed from test/xray/TestCases/Linux/always-never-instrument.cc)2
-rw-r--r--test/xray/TestCases/Posix/arg1-arg0-logging.cc (renamed from test/xray/TestCases/Linux/arg1-arg0-logging.cc)2
-rw-r--r--test/xray/TestCases/Posix/arg1-logger.cc (renamed from test/xray/TestCases/Linux/arg1-logger.cc)4
-rw-r--r--test/xray/TestCases/Posix/arg1-logging-implicit-this.cc (renamed from test/xray/TestCases/Linux/arg1-logging-implicit-this.cc)4
-rw-r--r--test/xray/TestCases/Posix/argv0-log-file-name.cc (renamed from test/xray/TestCases/Linux/argv0-log-file-name.cc)0
-rw-r--r--test/xray/TestCases/Posix/basic-filtering.cc (renamed from test/xray/TestCases/Linux/basic-filtering.cc)18
-rw-r--r--test/xray/TestCases/Posix/c-test.cc15
-rw-r--r--test/xray/TestCases/Posix/common-trampoline-alignment.cc (renamed from test/xray/TestCases/Linux/common-trampoline-alignment.cc)2
-rw-r--r--test/xray/TestCases/Posix/coverage-sample.cc (renamed from test/xray/TestCases/Linux/coverage-sample.cc)0
-rw-r--r--test/xray/TestCases/Posix/custom-event-handler-alignment.cc (renamed from test/xray/TestCases/Linux/custom-event-handler-alignment.cc)2
-rw-r--r--test/xray/TestCases/Posix/custom-event-logging.cc (renamed from test/xray/TestCases/Linux/custom-event-logging.cc)0
-rw-r--r--test/xray/TestCases/Posix/fdr-mode-inmemory.cc50
-rw-r--r--test/xray/TestCases/Posix/fdr-mode-multiple.cc76
-rw-r--r--test/xray/TestCases/Posix/fdr-mode.cc (renamed from test/xray/TestCases/Linux/fdr-mode.cc)67
-rw-r--r--test/xray/TestCases/Posix/fdr-single-thread.cc (renamed from test/xray/TestCases/Linux/fdr-single-thread.cc)8
-rw-r--r--test/xray/TestCases/Posix/fdr-thread-order.cc (renamed from test/xray/TestCases/Linux/fdr-thread-order.cc)10
-rw-r--r--test/xray/TestCases/Posix/fixedsize-logging.cc (renamed from test/xray/TestCases/Linux/fixedsize-logging.cc)0
-rw-r--r--test/xray/TestCases/Posix/fork_basic_logging.cc100
-rw-r--r--test/xray/TestCases/Posix/func-id-utils.cc (renamed from test/xray/TestCases/Linux/func-id-utils.cc)0
-rw-r--r--test/xray/TestCases/Posix/logging-modes.cc (renamed from test/xray/TestCases/Linux/logging-modes.cc)52
-rw-r--r--test/xray/TestCases/Posix/optional-inmemory-log.cc (renamed from test/xray/TestCases/Linux/optional-inmemory-log.cc)0
-rw-r--r--test/xray/TestCases/Posix/patching-unpatching.cc (renamed from test/xray/TestCases/Linux/patching-unpatching.cc)0
-rw-r--r--test/xray/TestCases/Posix/pic_test.cc (renamed from test/xray/TestCases/Linux/pic_test.cc)4
-rw-r--r--test/xray/TestCases/Posix/profiling-multi-threaded.cc57
-rw-r--r--test/xray/TestCases/Posix/profiling-single-threaded.cc65
-rw-r--r--test/xray/TestCases/Posix/quiet-start.cc (renamed from test/xray/TestCases/Linux/quiet-start.cc)2
-rw-r--r--test/xray/lit.cfg13
439 files changed, 10736 insertions, 1444 deletions
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index ab16f42d33d4..554ba5fa0f0e 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -61,7 +61,8 @@ if(COMPILER_RT_CAN_EXECUTE_TESTS)
compiler_rt_test_runtime(ubsan cfi)
compiler_rt_test_runtime(sanitizer_common)
- if(COMPILER_RT_BUILD_LIBFUZZER)
+ # OpenBSD not supporting asan, cannot run the tests
+ if(COMPILER_RT_BUILD_LIBFUZZER AND NOT "${CMAKE_SYSTEM_NAME}" STREQUAL "OpenBSD" AND NOT ANDROID)
compiler_rt_test_runtime(fuzzer)
endif()
@@ -78,6 +79,9 @@ if(COMPILER_RT_CAN_EXECUTE_TESTS)
if(COMPILER_RT_BUILD_XRAY)
compiler_rt_test_runtime(xray)
endif()
+ # ShadowCallStack does not yet provide a runtime with compiler-rt, the tests
+ # include their own minimal runtime
+ add_subdirectory(shadowcallstack)
endif()
if(COMPILER_RT_STANDALONE_BUILD)
diff --git a/test/asan/CMakeLists.txt b/test/asan/CMakeLists.txt
index 739ae56e782b..e6d1df5e039a 100644
--- a/test/asan/CMakeLists.txt
+++ b/test/asan/CMakeLists.txt
@@ -8,7 +8,7 @@ set(ASAN_DYNAMIC_TESTSUITES)
# unreliable. Remove the asan tests from check-all in this configuration.
set(SHADOW_MAPPING_UNRELIABLE FALSE)
if(OS_NAME MATCHES "Windows" AND CMAKE_SIZEOF_VOID_P EQUAL 8 AND
- ${CMAKE_SYSTEM_VERSION} LESS 6.2)
+ CMAKE_SYSTEM_VERSION LESS 6.2)
set(SHADOW_MAPPING_UNRELIABLE TRUE)
message(WARNING "Disabling ASan tests because they are unreliable on Windows 7 and earlier")
endif()
@@ -18,10 +18,10 @@ if (SHADOW_MAPPING_UNRELIABLE)
endif()
macro(get_bits_for_arch arch bits)
- if (${arch} MATCHES "i386|arm|mips|mipsel")
- set(${bits} 32)
- elseif (${arch} MATCHES "x86_64|powerpc64|powerpc64le|aarch64|mips64|mips64el|s390x")
+ if (${arch} MATCHES "x86_64|powerpc64|powerpc64le|aarch64|arm64|mips64|mips64el|s390x")
set(${bits} 64)
+ elseif (${arch} MATCHES "i386|arm|mips|mipsel")
+ set(${bits} 32)
else()
message(FATAL_ERROR "Unknown target architecture: ${arch}")
endif()
@@ -40,6 +40,9 @@ set(ASAN_TEST_ARCH ${ASAN_SUPPORTED_ARCH})
if(APPLE)
darwin_filter_host_archs(ASAN_SUPPORTED_ARCH ASAN_TEST_ARCH)
endif()
+if(OS_NAME MATCHES "SunOS")
+ list(REMOVE_ITEM ASAN_TEST_ARCH x86_64)
+endif()
foreach(arch ${ASAN_TEST_ARCH})
if(ANDROID)
@@ -48,10 +51,7 @@ foreach(arch ${ASAN_TEST_ARCH})
set(ASAN_TEST_TARGET_ARCH ${arch})
endif()
- set(ASAN_TEST_IOS "0")
- pythonize_bool(ASAN_TEST_IOS)
- set(ASAN_TEST_IOSSIM "0")
- pythonize_bool(ASAN_TEST_IOSSIM)
+ set(ASAN_TEST_APPLE_PLATFORM "osx")
string(TOLOWER "-${arch}-${OS_NAME}" ASAN_TEST_CONFIG_SUFFIX)
get_bits_for_arch(${arch} ASAN_TEST_BITS)
@@ -90,16 +90,13 @@ if(APPLE)
set(EXCLUDE_FROM_ALL ON)
set(ASAN_TEST_TARGET_CC ${COMPILER_RT_TEST_COMPILER})
- set(ASAN_TEST_IOS "1")
- pythonize_bool(ASAN_TEST_IOS)
set(ASAN_TEST_DYNAMIC True)
foreach(arch ${DARWIN_iossim_ARCHS})
- set(ASAN_TEST_IOSSIM "1")
- pythonize_bool(ASAN_TEST_IOSSIM)
+ set(ASAN_TEST_APPLE_PLATFORM "iossim")
set(ASAN_TEST_TARGET_ARCH ${arch})
set(ASAN_TEST_TARGET_CFLAGS "-arch ${arch} -isysroot ${DARWIN_iossim_SYSROOT} ${COMPILER_RT_TEST_COMPILER_CFLAGS}")
- set(ASAN_TEST_CONFIG_SUFFIX "-${arch}-iossim")
+ set(ASAN_TEST_CONFIG_SUFFIX "-${arch}-${ASAN_TEST_APPLE_PLATFORM}")
get_bits_for_arch(${arch} ASAN_TEST_BITS)
string(TOUPPER ${arch} ARCH_UPPER_CASE)
set(CONFIG_NAME "IOSSim${ARCH_UPPER_CASE}Config")
@@ -113,11 +110,10 @@ if(APPLE)
endforeach()
foreach (arch ${DARWIN_ios_ARCHS})
- set(ASAN_TEST_IOSSIM "0")
- pythonize_bool(ASAN_TEST_IOSSIM)
+ set(ASAN_TEST_APPLE_PLATFORM "ios")
set(ASAN_TEST_TARGET_ARCH ${arch})
set(ASAN_TEST_TARGET_CFLAGS "-arch ${arch} -isysroot ${DARWIN_ios_SYSROOT} ${COMPILER_RT_TEST_COMPILER_CFLAGS}")
- set(ASAN_TEST_CONFIG_SUFFIX "-${arch}-ios")
+ set(ASAN_TEST_CONFIG_SUFFIX "-${arch}-${ASAN_TEST_APPLE_PLATFORM}")
get_bits_for_arch(${arch} ASAN_TEST_BITS)
string(TOUPPER ${arch} ARCH_UPPER_CASE)
set(CONFIG_NAME "IOS${ARCH_UPPER_CASE}Config")
diff --git a/test/asan/TestCases/Darwin/asan_gen_prefixes.cc b/test/asan/TestCases/Darwin/asan_gen_prefixes.cc
index 9f3a66a7a708..fe337433d08d 100644
--- a/test/asan/TestCases/Darwin/asan_gen_prefixes.cc
+++ b/test/asan/TestCases/Darwin/asan_gen_prefixes.cc
@@ -1,4 +1,4 @@
-// Make sure __asan_gen_* strings have the correct prefixes on Darwin
+// Make sure ___asan_gen_* strings have the correct prefixes on Darwin
// ("L" in __TEXT,__cstring, "l" in __TEXT,__const
// RUN: %clang_asan %s -S -o %t.s
@@ -9,8 +9,8 @@
int x, y, z;
int main() { return 0; }
// CHECK: .section{{.*}}__TEXT,__const
-// CHECK: l___asan_gen_
+// CHECK: l____asan_gen_
// CHECK: .section{{.*}}__TEXT,__cstring,cstring_literals
-// CHECK: L___asan_gen_
-// CHECK: L___asan_gen_
-// CHECK: L___asan_gen_
+// CHECK: L____asan_gen_
+// CHECK: L____asan_gen_
+// CHECK: L____asan_gen_
diff --git a/test/asan/TestCases/Darwin/odr-lto.cc b/test/asan/TestCases/Darwin/odr-lto.cc
index 40abec5827d5..56dd89b164c2 100644
--- a/test/asan/TestCases/Darwin/odr-lto.cc
+++ b/test/asan/TestCases/Darwin/odr-lto.cc
@@ -3,15 +3,10 @@
// REQUIRES: lto
-// RUN: %clangxx_asan -DPART=0 -c %s -o %t-1.o -flto
-// RUN: %clangxx_asan -DPART=1 -c %s -o %t-2.o -flto
-// RUN: %clangxx_asan %t-1.o %t-2.o -o %t -flto
-// RUN: not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-ODR
-
// RUN: %clangxx_asan -DPART=0 -c %s -o %t-1.o -flto -mllvm -asan-use-private-alias
// RUN: %clangxx_asan -DPART=1 -c %s -o %t-2.o -flto -mllvm -asan-use-private-alias
// RUN: %clangxx_asan %t-1.o %t-2.o -o %t -flto
-// RUN: %env_asan_opts=use_odr_indicator=1 %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-NO-ODR
+// RUN: %env_asan_opts=use_odr_indicator=1 %run %t 2>&1 | FileCheck %s
#include <stdio.h>
#include <stdlib.h>
@@ -40,6 +35,5 @@ void putstest()
#endif // PART == 1
-// CHECK-ODR: ERROR: AddressSanitizer: odr-violation
-// CHECK-NO-ODR-NOT: ERROR: AddressSanitizer: odr-violation
-// CHECK-NO-ODR: Done.
+// CHECK-NOT: ERROR: AddressSanitizer: odr-violation
+// CHECK: Done.
diff --git a/test/asan/TestCases/Linux/activation-options.cc b/test/asan/TestCases/Linux/activation-options.cc
index 1a1ad3f8c499..39924c4b1d03 100644
--- a/test/asan/TestCases/Linux/activation-options.cc
+++ b/test/asan/TestCases/Linux/activation-options.cc
@@ -28,7 +28,6 @@
// RUN: ASAN_ACTIVATION_OPTIONS=include=%t.asan.options.%b %run %t --fix-name 2>&1 | \
// RUN: FileCheck %s --check-prefix=CHECK-HELP --check-prefix=CHECK-FOUND
-// XFAIL: arm-linux-gnueabi
// XFAIL: android
#if !defined(SHARED_LIB)
diff --git a/test/asan/TestCases/Linux/allocator_oom_test.cc b/test/asan/TestCases/Linux/allocator_oom_test.cc
index 6382003781ce..c450ae5bb8e9 100644
--- a/test/asan/TestCases/Linux/allocator_oom_test.cc
+++ b/test/asan/TestCases/Linux/allocator_oom_test.cc
@@ -32,7 +32,7 @@
// AArch64 bots fail on this test.
// TODO(alekseys): Android lit do not run ulimit on device.
// REQUIRES: shadow-scale-3
-// UNSUPPORTED: s390,android,arm,aarch64
+// UNSUPPORTED: s390,android,aarch64
#include <stdlib.h>
#include <string.h>
@@ -84,5 +84,5 @@ int main(int argc, char **argv) {
// CHECK-REALLOC: realloc:
// CHECK-MALLOC-REALLOC: realloc-after-malloc:
-// CHECK-CRASH: AddressSanitizer's allocator is terminating the process
+// CHECK-CRASH: SUMMARY: AddressSanitizer: out-of-memory
// CHECK-NULL: x: 0
diff --git a/test/asan/TestCases/Linux/clang_gcc_abi.cc b/test/asan/TestCases/Linux/clang_gcc_abi.cc
index 79710dc837b9..e0ae3f1f8afd 100644
--- a/test/asan/TestCases/Linux/clang_gcc_abi.cc
+++ b/test/asan/TestCases/Linux/clang_gcc_abi.cc
@@ -3,8 +3,7 @@
// RUN: %clangxx_asan -O2 -x c %s -o %t && not %run %t 2>&1 | FileCheck %s
// RUN: %clangxx_asan -O3 -x c %s -o %t && not %run %t 2>&1 | FileCheck %s
-// REQUIRES: arm-target-arch, fast-unwinder-works
-// XFAIL: armv7l-unknown-linux-gnueabihf
+// REQUIRES: (arm-target-arch || armhf-target-arch), fast-unwinder-works
#include <stdlib.h>
diff --git a/test/asan/TestCases/Linux/clone_test.cc b/test/asan/TestCases/Linux/clone_test.cc
index f6eb26100f5e..0b86238ccad6 100644
--- a/test/asan/TestCases/Linux/clone_test.cc
+++ b/test/asan/TestCases/Linux/clone_test.cc
@@ -5,7 +5,6 @@
// RUN: %clangxx_asan -O1 %s -o %t && %run %t | FileCheck %s
// RUN: %clangxx_asan -O2 %s -o %t && %run %t | FileCheck %s
// RUN: %clangxx_asan -O3 %s -o %t && %run %t | FileCheck %s
-// XFAIL: arm-linux-gnueabi
#include <stdio.h>
#include <sched.h>
diff --git a/test/asan/TestCases/Linux/coverage-missing.cc b/test/asan/TestCases/Linux/coverage-missing.cc
index 585aee69a029..32aada645deb 100644
--- a/test/asan/TestCases/Linux/coverage-missing.cc
+++ b/test/asan/TestCases/Linux/coverage-missing.cc
@@ -2,18 +2,18 @@
// First case: coverage from executable. main() is called on every code path.
// RUN: %clangxx_asan -fsanitize-coverage=func,trace-pc-guard %s -o %t -DFOOBAR -DMAIN
-// RUN: rm -rf %T/coverage-missing
-// RUN: mkdir -p %T/coverage-missing
-// RUN: cd %T/coverage-missing
-// RUN: %env_asan_opts=coverage=1:coverage_dir=%T/coverage-missing %run %t
+// RUN: rm -rf %t-dir
+// RUN: mkdir -p %t-dir
+// RUN: cd %t-dir
+// RUN: %env_asan_opts=coverage=1:coverage_dir=%t-dir %run %t
// RUN: %sancov print *.sancov > main.txt
// RUN: rm *.sancov
// RUN: count 1 < main.txt
-// RUN: %env_asan_opts=coverage=1:coverage_dir=%T/coverage-missing %run %t x
+// RUN: %env_asan_opts=coverage=1:coverage_dir=%t-dir %run %t x
// RUN: %sancov print *.sancov > foo.txt
// RUN: rm *.sancov
// RUN: count 3 < foo.txt
-// RUN: %env_asan_opts=coverage=1:coverage_dir=%T/coverage-missing %run %t x x
+// RUN: %env_asan_opts=coverage=1:coverage_dir=%t-dir %run %t x x
// RUN: %sancov print *.sancov > bar.txt
// RUN: rm *.sancov
// RUN: count 4 < bar.txt
@@ -26,18 +26,18 @@
// RUN: not grep "^<" %t.log
// Second case: coverage from DSO.
-// cd %T
+// cd %t-dir
// RUN: %clangxx_asan -fsanitize-coverage=func,trace-pc-guard %s -o %dynamiclib -DFOOBAR -shared -fPIC
// RUN: %clangxx_asan -fsanitize-coverage=func,trace-pc-guard %s %dynamiclib -o %t -DMAIN
// RUN: cd ..
-// RUN: rm -rf %T/coverage-missing
-// RUN: mkdir -p %T/coverage-missing
-// RUN: cd %T/coverage-missing
-// RUN: %env_asan_opts=coverage=1:coverage_dir=%T/coverage-missing %run %t x
+// RUN: rm -rf %t-dir
+// RUN: mkdir -p %t-dir
+// RUN: cd %t-dir
+// RUN: %env_asan_opts=coverage=1:coverage_dir=%t-dir %run %t x
// RUN: %sancov print %xdynamiclib_filename.*.sancov > foo.txt
// RUN: rm *.sancov
// RUN: count 2 < foo.txt
-// RUN: %env_asan_opts=coverage=1:coverage_dir=%T/coverage-missing %run %t x x
+// RUN: %env_asan_opts=coverage=1:coverage_dir=%t-dir %run %t x x
// RUN: %sancov print %xdynamiclib_filename.*.sancov > bar.txt
// RUN: rm *.sancov
// RUN: count 3 < bar.txt
diff --git a/test/asan/TestCases/Linux/interception_readdir_r_test.cc b/test/asan/TestCases/Linux/interception_readdir_r_test.cc
index 93b553c3744f..987dff27523a 100644
--- a/test/asan/TestCases/Linux/interception_readdir_r_test.cc
+++ b/test/asan/TestCases/Linux/interception_readdir_r_test.cc
@@ -1,15 +1,18 @@
// FIXME: https://code.google.com/p/address-sanitizer/issues/detail?id=316
// XFAIL: android
+
+// RUN: rm -rf %t-dir
+// RUN: mkdir -p %t-dir
//
-// RUN: %clangxx_asan -O0 %s -DTEMP_DIR='"'"%T"'"' -o %t && %run %t 2>&1 | FileCheck %s
-// RUN: %clangxx_asan -O1 %s -DTEMP_DIR='"'"%T"'"' -o %t && %run %t 2>&1 | FileCheck %s
-// RUN: %clangxx_asan -O2 %s -DTEMP_DIR='"'"%T"'"' -o %t && %run %t 2>&1 | FileCheck %s
-// RUN: %clangxx_asan -O3 %s -DTEMP_DIR='"'"%T"'"' -o %t && %run %t 2>&1 | FileCheck %s
+// RUN: %clangxx_asan -O0 %s -DTEMP_DIR='"'"%t-dir"'"' -o %t && %run %t 2>&1 | FileCheck %s
+// RUN: %clangxx_asan -O1 %s -DTEMP_DIR='"'"%t-dir"'"' -o %t && %run %t 2>&1 | FileCheck %s
+// RUN: %clangxx_asan -O2 %s -DTEMP_DIR='"'"%t-dir"'"' -o %t && %run %t 2>&1 | FileCheck %s
+// RUN: %clangxx_asan -O3 %s -DTEMP_DIR='"'"%t-dir"'"' -o %t && %run %t 2>&1 | FileCheck %s
//
-// RUN: %clangxx_asan -O0 %s -D_FILE_OFFSET_BITS=64 -DTEMP_DIR='"'"%T"'"' -o %t && %run %t 2>&1 | FileCheck %s
-// RUN: %clangxx_asan -O1 %s -D_FILE_OFFSET_BITS=64 -DTEMP_DIR='"'"%T"'"' -o %t && %run %t 2>&1 | FileCheck %s
-// RUN: %clangxx_asan -O2 %s -D_FILE_OFFSET_BITS=64 -DTEMP_DIR='"'"%T"'"' -o %t && %run %t 2>&1 | FileCheck %s
-// RUN: %clangxx_asan -O3 %s -D_FILE_OFFSET_BITS=64 -DTEMP_DIR='"'"%T"'"' -o %t && %run %t 2>&1 | FileCheck %s
+// RUN: %clangxx_asan -O0 %s -D_FILE_OFFSET_BITS=64 -DTEMP_DIR='"'"%t-dir"'"' -o %t && %run %t 2>&1 | FileCheck %s
+// RUN: %clangxx_asan -O1 %s -D_FILE_OFFSET_BITS=64 -DTEMP_DIR='"'"%t-dir"'"' -o %t && %run %t 2>&1 | FileCheck %s
+// RUN: %clangxx_asan -O2 %s -D_FILE_OFFSET_BITS=64 -DTEMP_DIR='"'"%t-dir"'"' -o %t && %run %t 2>&1 | FileCheck %s
+// RUN: %clangxx_asan -O3 %s -D_FILE_OFFSET_BITS=64 -DTEMP_DIR='"'"%t-dir"'"' -o %t && %run %t 2>&1 | FileCheck %s
#include <dirent.h>
#include <memory.h>
diff --git a/test/asan/TestCases/Linux/local_alias.cc b/test/asan/TestCases/Linux/local_alias.cc
index 8c80f878594d..266d3fe6bc8f 100644
--- a/test/asan/TestCases/Linux/local_alias.cc
+++ b/test/asan/TestCases/Linux/local_alias.cc
@@ -7,10 +7,6 @@
// FIXME: https://github.com/google/sanitizers/issues/316
// XFAIL: android
//
-// This test requires the integrated assembler to be the default.
-// XFAIL: target-is-mips64
-// XFAIL: target-is-mips64el
-//
// RUN: %clangxx_asan -DBUILD_INSTRUMENTED_DSO=1 -fPIC -shared -mllvm -asan-use-private-alias %s -o %t-INSTRUMENTED-SO.so
// RUN: %clangxx -DBUILD_UNINSTRUMENTED_DSO=1 -fPIC -shared %s -o %t-UNINSTRUMENTED-SO.so
// RUN: %clangxx %s -c -mllvm -asan-use-private-alias -o %t.o
diff --git a/test/asan/TestCases/Linux/long-object-path.cc b/test/asan/TestCases/Linux/long-object-path.cc
new file mode 100644
index 000000000000..592b0abb07d7
--- /dev/null
+++ b/test/asan/TestCases/Linux/long-object-path.cc
@@ -0,0 +1,7 @@
+// RUN: mkdir -p %T/a-long-directory-name-to-test-allocations-for-exceptions-in-_dl_lookup_symbol_x-since-glibc-2.27
+// RUN: %clangxx_asan -g %s -o %T/long-object-path
+// RUN: %run %T/a-*/../a-*/../a-*/../a-*/../a-*/../a-*/../a-*/../a-*/../long-object-path
+
+int main(void) {
+ return 0;
+}
diff --git a/test/asan/TestCases/Linux/odr-violation.cc b/test/asan/TestCases/Linux/odr-violation.cc
index d909143a86a1..70437a8321b9 100644
--- a/test/asan/TestCases/Linux/odr-violation.cc
+++ b/test/asan/TestCases/Linux/odr-violation.cc
@@ -1,10 +1,6 @@
// FIXME: https://code.google.com/p/address-sanitizer/issues/detail?id=316
// XFAIL: android
//
-// This test requires the integrated assembler to be the default.
-// XFAIL: target-is-mips64
-// XFAIL: target-is-mips64el
-//
// We use fast_unwind_on_malloc=0 to have full unwinding even w/o frame
// pointers. This setting is not on by default because it's too expensive.
//
diff --git a/test/asan/TestCases/Linux/pvalloc-overflow.cc b/test/asan/TestCases/Linux/pvalloc-overflow.cc
deleted file mode 100644
index b47c6266b93b..000000000000
--- a/test/asan/TestCases/Linux/pvalloc-overflow.cc
+++ /dev/null
@@ -1,41 +0,0 @@
-// RUN: %clangxx_asan %s -o %t
-// RUN: ASAN_OPTIONS=allocator_may_return_null=0 not %run %t m1 2>&1 | FileCheck %s
-// RUN: ASAN_OPTIONS=allocator_may_return_null=1 %run %t m1 2>&1
-// RUN: ASAN_OPTIONS=allocator_may_return_null=0 not %run %t psm1 2>&1 | FileCheck %s
-// RUN: ASAN_OPTIONS=allocator_may_return_null=1 %run %t psm1 2>&1
-
-// UNSUPPORTED: freebsd, android
-
-// Checks that pvalloc overflows are caught. If the allocator is allowed to
-// return null, the errno should be set to ENOMEM.
-
-#include <assert.h>
-#include <errno.h>
-#include <malloc.h>
-#include <stdint.h>
-#include <string.h>
-#include <unistd.h>
-
-int main(int argc, char *argv[]) {
- void *p;
- size_t page_size;
-
- assert(argc == 2);
-
- page_size = sysconf(_SC_PAGESIZE);
-
- if (!strcmp(argv[1], "m1")) {
- p = pvalloc((uintptr_t)-1);
- assert(!p);
- assert(errno == ENOMEM);
- }
- if (!strcmp(argv[1], "psm1")) {
- p = pvalloc((uintptr_t)-(page_size - 1));
- assert(!p);
- assert(errno == ENOMEM);
- }
-
- return 0;
-}
-
-// CHECK: AddressSanitizer's allocator is terminating the process
diff --git a/test/asan/TestCases/Linux/quarantine_size_mb.cc b/test/asan/TestCases/Linux/quarantine_size_mb.cc
index 239eeabee170..f7bccbfbe8db 100644
--- a/test/asan/TestCases/Linux/quarantine_size_mb.cc
+++ b/test/asan/TestCases/Linux/quarantine_size_mb.cc
@@ -5,6 +5,10 @@
// RUN: %env_asan_opts=quarantine_size_mb=10:quarantine_size=20:verbosity=1 not %run %t 2>&1 | FileCheck %s --check-prefix=BOTH
// RUN: %env_asan_opts=quarantine_size_mb=1000:hard_rss_limit_mb=50 not %run %t 2>&1 | FileCheck %s --check-prefix=RSS_LIMIT
// RUN: %env_asan_opts=hard_rss_limit_mb=20 not %run %t 2>&1 | FileCheck %s --check-prefix=RSS_LIMIT
+
+// https://github.com/google/sanitizers/issues/981
+// UNSUPPORTED: android-26
+
#include <string.h>
char *g;
diff --git a/test/asan/TestCases/Linux/stack-trace-dlclose.cc b/test/asan/TestCases/Linux/stack-trace-dlclose.cc
index e604f1e4f73f..899e0dfc6bda 100644
--- a/test/asan/TestCases/Linux/stack-trace-dlclose.cc
+++ b/test/asan/TestCases/Linux/stack-trace-dlclose.cc
@@ -1,8 +1,10 @@
// FIXME: https://code.google.com/p/address-sanitizer/issues/detail?id=316
// XFAIL: android
//
-// RUN: %clangxx_asan -DSHARED %s -shared -o %T/stack_trace_dlclose.so -fPIC
-// RUN: %clangxx_asan -DSO_DIR=\"%T\" %s %libdl -o %t
+// RUN: rm -rf %t-dir
+// RUN: mkdir -p %t-dir
+// RUN: %clangxx_asan -DSHARED %s -shared -o %t-dir/stack_trace_dlclose.so -fPIC
+// RUN: %clangxx_asan -DSO_DIR=\"%t-dir\" %s %libdl -o %t
// RUN: %env_asan_opts=exitcode=0 %run %t 2>&1 | FileCheck %s
// REQUIRES: stable-runtime
diff --git a/test/asan/TestCases/Linux/syscalls.cc b/test/asan/TestCases/Linux/syscalls.cc
index bcdd5bc82119..ec14bca76129 100644
--- a/test/asan/TestCases/Linux/syscalls.cc
+++ b/test/asan/TestCases/Linux/syscalls.cc
@@ -1,6 +1,3 @@
-// FIXME: https://code.google.com/p/address-sanitizer/issues/detail?id=316
-// XFAIL: android
-//
// RUN: %clangxx_asan -O0 %s -o %t && not %run %t 2>&1 | FileCheck %s
// RUN: %clangxx_asan -O3 %s -o %t && not %run %t 2>&1 | FileCheck %s
diff --git a/test/asan/TestCases/Posix/asan-sigbus.cpp b/test/asan/TestCases/Posix/asan-sigbus.cpp
index c91ecbd756f6..baf1e4266866 100644
--- a/test/asan/TestCases/Posix/asan-sigbus.cpp
+++ b/test/asan/TestCases/Posix/asan-sigbus.cpp
@@ -5,6 +5,8 @@
// RUN: %env_asan_opts=handle_sigbus=0 not --crash %run %t 2>&1 | FileCheck %s
// UNSUPPORTED: ios
+// Instead of getting a SIGBUS error, we get a SIGSEGV
+// XFAIL: freebsd
#include <assert.h>
#include <fcntl.h>
@@ -14,6 +16,10 @@
#include <unistd.h>
#include <string>
+#ifndef MAP_FILE
+#define MAP_FILE 0
+#endif
+
char array[4096];
int main(int argc, char **argv) {
int fd = open((std::string(argv[0]) + ".m").c_str(), O_RDWR | O_CREAT, 0700);
diff --git a/test/asan/TestCases/Posix/asan-symbolize-bad-path.cc b/test/asan/TestCases/Posix/asan-symbolize-bad-path.cc
index 22c03e8ddced..3f93122e9099 100644
--- a/test/asan/TestCases/Posix/asan-symbolize-bad-path.cc
+++ b/test/asan/TestCases/Posix/asan-symbolize-bad-path.cc
@@ -1,4 +1,4 @@
// Test that asan_symbolize does not hang when provided with an non-existing
// path.
-// RUN: echo '#0 0xabcdabcd (%T/bad/path+0x1234)' | %asan_symbolize | FileCheck %s
+// RUN: echo '#0 0xabcdabcd (%t/bad/path+0x1234)' | %asan_symbolize | FileCheck %s
// CHECK: #0 0xabcdabcd
diff --git a/test/asan/TestCases/Posix/concurrent_overflow.cc b/test/asan/TestCases/Posix/concurrent_overflow.cc
index e9b9899c31a2..345b546851ba 100644
--- a/test/asan/TestCases/Posix/concurrent_overflow.cc
+++ b/test/asan/TestCases/Posix/concurrent_overflow.cc
@@ -20,11 +20,12 @@ static void *start_routine(void *arg) {
int main(void) {
const int n_threads = 8;
int i, counter = n_threads;
- pthread_t thread;
+ pthread_t thread[n_threads];
for (i = 0; i < n_threads; ++i)
- pthread_create(&thread, NULL, &start_routine, (void *)&counter);
- sleep(5);
+ pthread_create(&thread[i], NULL, &start_routine, (void *)&counter);
+ for (i = 0; i < n_threads; ++i)
+ pthread_join(thread[i], NULL);
return 0;
}
diff --git a/test/asan/TestCases/Posix/coverage-fork.cc b/test/asan/TestCases/Posix/coverage-fork.cc
index da6e3c2c1b38..22d2e35842a8 100644
--- a/test/asan/TestCases/Posix/coverage-fork.cc
+++ b/test/asan/TestCases/Posix/coverage-fork.cc
@@ -1,6 +1,6 @@
// RUN: %clangxx_asan -fsanitize-coverage=func,trace-pc-guard %s -o %t
-// RUN: rm -rf %T/coverage-fork
-// RUN: mkdir -p %T/coverage-fork && cd %T/coverage-fork
+// RUN: rm -rf %t-dir
+// RUN: mkdir -p %t-dir && cd %t-dir
// RUN: %env_asan_opts=coverage=1:verbosity=1 %run %t 2>&1 | FileCheck %s
//
// UNSUPPORTED: android
diff --git a/test/asan/TestCases/Posix/coverage-reset.cc b/test/asan/TestCases/Posix/coverage-reset.cc
index 201bf8e53252..6d76a309b76f 100644
--- a/test/asan/TestCases/Posix/coverage-reset.cc
+++ b/test/asan/TestCases/Posix/coverage-reset.cc
@@ -1,6 +1,6 @@
// RUN: %clangxx_asan -fsanitize-coverage=func,trace-pc-guard -DSHARED %s -shared -o %dynamiclib -fPIC %ld_flags_rpath_so
// RUN: %clangxx_asan -fsanitize-coverage=func,trace-pc-guard %s %ld_flags_rpath_exe -o %t
-// RUN: rm -rf %T/coverage-reset && mkdir -p %T/coverage-reset && cd %T/coverage-reset
+// RUN: rm -rf %t-dir && mkdir -p %t-dir && cd %t-dir
// RUN: %env_asan_opts=coverage=1:verbosity=1 %run %t 2>&1 | FileCheck %s
//
// UNSUPPORTED: ios
diff --git a/test/asan/TestCases/Posix/coverage.cc b/test/asan/TestCases/Posix/coverage.cc
index a78560a72a00..12a88402eb5a 100644
--- a/test/asan/TestCases/Posix/coverage.cc
+++ b/test/asan/TestCases/Posix/coverage.cc
@@ -1,6 +1,6 @@
// RUN: %clangxx_asan -fsanitize-coverage=func,trace-pc-guard -DSHARED %s -shared -o %dynamiclib -fPIC %ld_flags_rpath_so
// RUN: %clangxx_asan -fsanitize-coverage=func,trace-pc-guard %s %ld_flags_rpath_exe -o %t
-// RUN: rm -rf %T/coverage && mkdir -p %T/coverage && cd %T/coverage
+// RUN: rm -rf %t-dir && mkdir -p %t-dir && cd %t-dir
// RUN: %env_asan_opts=coverage=1:verbosity=1 %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-main
// RUN: %sancov print coverage.*sancov 2>&1 | FileCheck %s --check-prefix=CHECK-SANCOV1
// RUN: %env_asan_opts=coverage=1:verbosity=1 %run %t foo 2>&1 | FileCheck %s --check-prefix=CHECK-foo
@@ -14,7 +14,7 @@
// RUN: %sancov print merged-cov 2>&1 | FileCheck %s --check-prefix=CHECK-SANCOV2
// RUN: %env_asan_opts=coverage=1:verbosity=1 not %run %t foo bar 4 2>&1 | FileCheck %s --check-prefix=CHECK-report
// RUN: %env_asan_opts=coverage=1:verbosity=1 not %run %t foo bar 4 5 2>&1 | FileCheck %s --check-prefix=CHECK-segv
-// RUN: rm -r %T/coverage
+// RUN: cd .. && rm -rf %t-dir
//
// https://code.google.com/p/address-sanitizer/issues/detail?id=263
// XFAIL: android
diff --git a/test/asan/TestCases/Posix/fgets_fputs.cc b/test/asan/TestCases/Posix/fgets_fputs.cc
new file mode 100644
index 000000000000..34c952f2e02e
--- /dev/null
+++ b/test/asan/TestCases/Posix/fgets_fputs.cc
@@ -0,0 +1,54 @@
+// RUN: %clangxx_asan -g %s -o %t
+// RUN: not %run %t 1 2>&1 | FileCheck %s --check-prefix=CHECK-FGETS
+// RUN: not %run %t 2 2>&1 | FileCheck %s --check-prefix=CHECK-FPUTS
+// RUN: not %run %t 3 2>&1 | FileCheck %s --check-prefix=CHECK-PUTS
+
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+int test_fgets(const char *testfile) {
+ char buf[2];
+ FILE *fp = fopen(testfile, "r");
+ assert(fp);
+ fgets(buf, sizeof(buf) + 1, fp); // BOOM
+ fclose(fp);
+ return 0;
+}
+
+int test_fputs() {
+ char buf[1] = {'x'}; // Note: not nul-terminated
+ FILE *fp = fopen("/dev/null", "w");
+ assert(fp);
+ fputs(buf, fp); // BOOM
+ fclose(fp);
+ return 0;
+}
+
+int test_puts() {
+ char *p = strdup("x");
+ free(p);
+ puts(p); // BOOM
+ return 0;
+}
+
+int main(int argc, char *argv[]) {
+ assert(argc >= 2);
+ int testno = argv[1][0] - '0';
+ if (testno == 1) {
+ return test_fgets(argv[0]);
+ }
+ if (testno == 2)
+ return test_fputs();
+ if (testno == 3)
+ return test_puts();
+ return 1;
+}
+
+// CHECK-FGETS: {{.*ERROR: AddressSanitizer: stack-buffer-overflow}}
+// CHECK-FGETS: #{{.*}} in {{(wrap_|__interceptor_)?}}fgets
+// CHECK-FPUTS: {{.*ERROR: AddressSanitizer: stack-buffer-overflow}}
+// CHECK-FPUTS: #{{.*}} in {{(wrap_|__interceptor_)?}}fputs
+// CHECK-PUTS: {{.*ERROR: AddressSanitizer: heap-use-after-free}}
+// CHECK-PUTS: #{{.*}} in {{(wrap_|__interceptor_)?}}puts
diff --git a/test/asan/TestCases/Posix/fread_fwrite.cc b/test/asan/TestCases/Posix/fread_fwrite.cc
index c0629260418a..640248860179 100644
--- a/test/asan/TestCases/Posix/fread_fwrite.cc
+++ b/test/asan/TestCases/Posix/fread_fwrite.cc
@@ -1,6 +1,9 @@
// RUN: %clangxx_asan -g %s -o %t
// RUN: not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-FWRITE
// RUN: not %run %t 1 2>&1 | FileCheck %s --check-prefix=CHECK-FREAD
+//
+// On FreeBSD stack overflow error instead
+// XFAIL: freebsd
#include <stdio.h>
#include <stdlib.h>
diff --git a/test/asan/TestCases/Posix/glob.cc b/test/asan/TestCases/Posix/glob.cc
index 46d4a0d8d43d..16b4ace8efc5 100644
--- a/test/asan/TestCases/Posix/glob.cc
+++ b/test/asan/TestCases/Posix/glob.cc
@@ -4,7 +4,6 @@
//
// RUN: %clangxx_asan -O0 %s -o %t && %run %t %p 2>&1 | FileCheck %s
// RUN: %clangxx_asan -O3 %s -o %t && %run %t %p 2>&1 | FileCheck %s
-// XFAIL: arm-linux-gnueabi
#include <assert.h>
#include <glob.h>
diff --git a/test/asan/TestCases/Posix/invalid-pointer-pairs-threads.cc b/test/asan/TestCases/Posix/invalid-pointer-pairs-threads.cc
index 28be9b59117b..ee8a1c70cf03 100644
--- a/test/asan/TestCases/Posix/invalid-pointer-pairs-threads.cc
+++ b/test/asan/TestCases/Posix/invalid-pointer-pairs-threads.cc
@@ -1,7 +1,7 @@
// RUN: %clangxx_asan -O0 %s -pthread -o %t -mllvm -asan-detect-invalid-pointer-pair
-// RUN: %env_asan_opts=detect_invalid_pointer_pairs=1 %run %t a 2>&1 | FileCheck %s -check-prefix=OK -allow-empty
-// RUN: %env_asan_opts=detect_invalid_pointer_pairs=1 not %run %t b 2>&1 | FileCheck %s -check-prefix=B
+// RUN: %env_asan_opts=detect_invalid_pointer_pairs=2 %run %t a 2>&1 | FileCheck %s -check-prefix=OK -allow-empty
+// RUN: %env_asan_opts=detect_invalid_pointer_pairs=2 not %run %t b 2>&1 | FileCheck %s -check-prefix=B
// pthread barriers are not available on OS X
// UNSUPPORTED: darwin
diff --git a/test/asan/TestCases/Posix/ioctl.cc b/test/asan/TestCases/Posix/ioctl.cc
index 6cf9fa8e3cd3..7269dfddb9b3 100644
--- a/test/asan/TestCases/Posix/ioctl.cc
+++ b/test/asan/TestCases/Posix/ioctl.cc
@@ -10,6 +10,10 @@
#include <sys/socket.h>
#include <unistd.h>
+#if defined(__sun__) && defined(__svr4__)
+#include <sys/filio.h>
+#endif
+
int main(int argc, char **argv) {
int fd = socket(AF_INET, SOCK_DGRAM, 0);
diff --git a/test/asan/TestCases/Posix/lto-constmerge-odr.cc b/test/asan/TestCases/Posix/lto-constmerge-odr.cc
new file mode 100644
index 000000000000..9dc1397f6f0e
--- /dev/null
+++ b/test/asan/TestCases/Posix/lto-constmerge-odr.cc
@@ -0,0 +1,14 @@
+// RUN: %clangxx_asan -O3 -flto %s -o %t
+// RUN: %run %t 2>&1
+
+// REQUIRES: lto
+
+int main(int argc, const char * argv[]) {
+ struct { long width, height; } a = {16, 16};
+ struct { long width, height; } b = {16, 16};
+
+ // Just to make sure 'a' and 'b' don't get optimized out.
+ asm volatile("" : : "r" (&a), "r" (&b));
+
+ return 0;
+}
diff --git a/test/asan/TestCases/Posix/mmap_limit_mb.cc b/test/asan/TestCases/Posix/mmap_limit_mb.cc
index 379524121a88..508c03fbcb16 100644
--- a/test/asan/TestCases/Posix/mmap_limit_mb.cc
+++ b/test/asan/TestCases/Posix/mmap_limit_mb.cc
@@ -9,7 +9,7 @@
// RUN: %env_asan_opts=mmap_limit_mb=300 not %run %t 500 1000000 2>&1 | FileCheck %s
//
// FIXME: Windows doesn't implement mmap_limit_mb.
-// XFAIL: arm-linux-gnueabi,win32
+// XFAIL: win32
#include <assert.h>
#include <stdlib.h>
diff --git a/test/asan/TestCases/Posix/no_asan_gen_globals.c b/test/asan/TestCases/Posix/no_asan_gen_globals.c
index c686f83ac4a8..994f827974be 100644
--- a/test/asan/TestCases/Posix/no_asan_gen_globals.c
+++ b/test/asan/TestCases/Posix/no_asan_gen_globals.c
@@ -1,12 +1,10 @@
// FIXME: https://code.google.com/p/address-sanitizer/issues/detail?id=316
// XFAIL: android
-// FIXME: http://llvm.org/bugs/show_bug.cgi?id=22682
-// REQUIRES: asan-64-bits
-// Make sure __asan_gen_* strings do not end up in the symbol table.
+// Make sure ___asan_gen_* strings do not end up in the symbol table.
// RUN: %clang_asan %s -o %t.exe
// RUN: nm %t.exe | FileCheck %s
int x, y, z;
int main() { return 0; }
-// CHECK-NOT: __asan_gen_
+// CHECK-NOT: ___asan_gen_
diff --git a/test/asan/TestCases/Posix/shared-lib-test.cc b/test/asan/TestCases/Posix/shared-lib-test.cc
index 305942a0792d..6de6d9fdfe5b 100644
--- a/test/asan/TestCases/Posix/shared-lib-test.cc
+++ b/test/asan/TestCases/Posix/shared-lib-test.cc
@@ -6,7 +6,6 @@
// RUN: %clangxx_asan -O2 %s %libdl -o %t && not %run %t 2>&1 | FileCheck %s
// RUN: %clangxx_asan -O3 -DSHARED_LIB %s -fPIC -shared -o %t-so.so
// RUN: %clangxx_asan -O3 %s %libdl -o %t && not %run %t 2>&1 | FileCheck %s
-// XFAIL: arm-linux-gnueabi
#if !defined(SHARED_LIB)
#include <dlfcn.h>
diff --git a/test/asan/TestCases/Posix/stack-use-after-return.cc b/test/asan/TestCases/Posix/stack-use-after-return.cc
index 2da1a0590db7..237c880f8e61 100644
--- a/test/asan/TestCases/Posix/stack-use-after-return.cc
+++ b/test/asan/TestCases/Posix/stack-use-after-return.cc
@@ -16,9 +16,11 @@
// This test runs out of stack on AArch64.
// UNSUPPORTED: aarch64
+// stack size log lower than expected
+// XFAIL: freebsd
-// FIXME: Fix this test for dynamic runtime on armhf-linux.
-// UNSUPPORTED: armhf-linux && asan-dynamic-runtime
+// FIXME: Fix this test for dynamic runtime on arm linux.
+// UNSUPPORTED: (arm-linux || armhf-linux) && asan-dynamic-runtime
#include <limits.h>
#include <pthread.h>
@@ -95,7 +97,7 @@ int main(int argc, char **argv) {
if (stacksize_check != desired_stack_size) {
fprintf(stderr, "Unable to set stack size to %d, the stack size is %d.\n",
- desired_stack_size, stacksize_check);
+ (int)desired_stack_size, (int)stacksize_check);
abort();
}
}
diff --git a/test/asan/TestCases/Posix/start-deactivated.cc b/test/asan/TestCases/Posix/start-deactivated.cc
index 2870ffb2f454..736d7f698b17 100644
--- a/test/asan/TestCases/Posix/start-deactivated.cc
+++ b/test/asan/TestCases/Posix/start-deactivated.cc
@@ -18,7 +18,6 @@
// RUN: %env_asan_opts=start_deactivated=1 \
// RUN: ASAN_ACTIVATION_OPTIONS=help=1,handle_segv=0,verbosity=1 not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-UNSUPPORTED
-// XFAIL: arm-linux-gnueabi
// UNSUPPORTED: ios
// END.
diff --git a/test/asan/TestCases/Posix/strndup_oob_test.cc b/test/asan/TestCases/Posix/strndup_oob_test.cc
index 7ea0b7a33400..326ddcfd6b06 100644
--- a/test/asan/TestCases/Posix/strndup_oob_test.cc
+++ b/test/asan/TestCases/Posix/strndup_oob_test.cc
@@ -7,7 +7,7 @@
// RUN: %clangxx_asan -O3 -xc %s -o %t && not %run %t 2>&1 | FileCheck %s
// Unwind problem on arm: "main" is missing from the allocation stack trace.
-// UNSUPPORTED: win32,s390,armv7l-unknown-linux-gnueabihf
+// UNSUPPORTED: win32,s390,arm && !fast-unwinder-works
#include <string.h>
diff --git a/test/asan/TestCases/Posix/strndup_oob_test2.cc b/test/asan/TestCases/Posix/strndup_oob_test2.cc
index 903f5e65f98f..44df6bda9c83 100644
--- a/test/asan/TestCases/Posix/strndup_oob_test2.cc
+++ b/test/asan/TestCases/Posix/strndup_oob_test2.cc
@@ -7,7 +7,7 @@
// RUN: %clang_asan -O3 -xc %s -o %t && not %run %t 2>&1 | FileCheck %s
// Unwind problem on arm: "main" is missing from the allocation stack trace.
-// UNSUPPORTED: win32,s390,armv7l-unknown-linux-gnueabihf
+// UNSUPPORTED: win32,s390,arm && !fast-unwinder-works
#include <string.h>
@@ -19,4 +19,4 @@ int main(int argc, char **argv) {
// CHECK: AddressSanitizer: global-buffer-overflow
// CHECK: {{.*}}main {{.*}}.cc:[[@LINE-2]]
return *copy;
-} \ No newline at end of file
+}
diff --git a/test/asan/TestCases/Windows/coverage-basic.cc b/test/asan/TestCases/Windows/coverage-basic.cc
index 918872f18f91..1469e1c30ae3 100644
--- a/test/asan/TestCases/Windows/coverage-basic.cc
+++ b/test/asan/TestCases/Windows/coverage-basic.cc
@@ -1,5 +1,5 @@
-// RUN: rm -rf %T/coverage-basic
-// RUN: mkdir %T/coverage-basic && cd %T/coverage-basic
+// RUN: rm -rf %t-dir
+// RUN: mkdir %t-dir && cd %t-dir
// RUN: %clangxx_asan -fsanitize-coverage=func %s -o test.exe
// RUN: %env_asan_opts=coverage=1 %run ./test.exe
//
diff --git a/test/asan/TestCases/Windows/fuse-lld-globals.cc b/test/asan/TestCases/Windows/fuse-lld-globals.cc
new file mode 100644
index 000000000000..4148d562fb40
--- /dev/null
+++ b/test/asan/TestCases/Windows/fuse-lld-globals.cc
@@ -0,0 +1,18 @@
+// RUN: %clangxx_asan -fuse-ld=lld -O3 %s -o %t && not %run %t 2>&1 | FileCheck %s
+
+#include <string.h>
+int main(int argc, char **argv) {
+ static char XXX[10];
+ static char YYY[10];
+ static char ZZZ[10];
+ memset(XXX, 0, 10);
+ memset(YYY, 0, 10);
+ memset(ZZZ, 0, 10);
+ int res = YYY[argc * 10]; // BOOOM
+ // CHECK: {{READ of size 1 at 0x.* thread T0}}
+ // CHECK: {{ #0 0x.* in main .*fuse-lld-globals.cc:}}[[@LINE-2]]
+ // CHECK: {{0x.* is located 0 bytes to the right of global variable}}
+ // CHECK: {{.*YYY.* of size 10}}
+ res += XXX[argc] + ZZZ[argc];
+ return res;
+}
diff --git a/test/asan/TestCases/Windows/oom.cc b/test/asan/TestCases/Windows/oom.cc
index 71a9c2a759a9..4d68c145eca7 100644
--- a/test/asan/TestCases/Windows/oom.cc
+++ b/test/asan/TestCases/Windows/oom.cc
@@ -8,5 +8,5 @@ int main() {
while (true) {
void *ptr = malloc(200 * 1024 * 1024); // 200MB
}
-// CHECK: allocator is terminating the process instead of returning 0
+// CHECK: SUMMARY: AddressSanitizer: out-of-memory
}
diff --git a/test/asan/TestCases/Windows/user-exception.cc b/test/asan/TestCases/Windows/user-exception.cc
new file mode 100644
index 000000000000..4cff23fbc02f
--- /dev/null
+++ b/test/asan/TestCases/Windows/user-exception.cc
@@ -0,0 +1,36 @@
+// RUN: %clang_cl_asan -O0 %s -Fe%t
+// RUN: env ASAN_OPTIONS=handle_segv=0 %run %t 2>&1 | FileCheck %s --check-prefix=USER
+// RUN: env ASAN_OPTIONS=handle_segv=1 not %run %t 2>&1 | FileCheck %s --check-prefix=ASAN
+// Test the default.
+// RUN: not %run %t 2>&1 | FileCheck %s --check-prefix=ASAN
+
+// This test exits zero when its unhandled exception filter is set. ASan should
+// not disturb it when handle_segv=0.
+
+// USER: in main
+// USER: in SEHHandler
+
+// ASAN: in main
+// ASAN: ERROR: AddressSanitizer: access-violation
+
+#include <windows.h>
+#include <stdio.h>
+
+static long WINAPI SEHHandler(EXCEPTION_POINTERS *info) {
+ DWORD exception_code = info->ExceptionRecord->ExceptionCode;
+ if (exception_code == EXCEPTION_ACCESS_VIOLATION) {
+ fprintf(stderr, "in SEHHandler\n");
+ fflush(stderr);
+ TerminateProcess(GetCurrentProcess(), 0);
+ }
+ return EXCEPTION_CONTINUE_SEARCH;
+}
+
+int main() {
+ SetUnhandledExceptionFilter(SEHHandler);
+ fprintf(stderr, "in main\n");
+ fflush(stderr);
+
+ volatile int *p = nullptr;
+ *p = 42;
+}
diff --git a/test/asan/TestCases/alloca_constant_size.cc b/test/asan/TestCases/alloca_constant_size.cc
index 57aa315705f9..8910ea9f8d8e 100644
--- a/test/asan/TestCases/alloca_constant_size.cc
+++ b/test/asan/TestCases/alloca_constant_size.cc
@@ -6,13 +6,14 @@
#include <stdio.h>
#include <string.h>
+#include <stdlib.h>
// MSVC provides _alloca instead of alloca.
#if defined(_MSC_VER) && !defined(alloca)
# define alloca _alloca
-#elif defined(__FreeBSD__) || defined(__NetBSD__)
-#include <stdlib.h>
-#else
+#endif
+
+#if defined(__sun__) && defined(__svr4__)
#include <alloca.h>
#endif
diff --git a/test/asan/TestCases/alloca_loop_unpoisoning.cc b/test/asan/TestCases/alloca_loop_unpoisoning.cc
index 1efada10979a..f9d32aafdc8f 100644
--- a/test/asan/TestCases/alloca_loop_unpoisoning.cc
+++ b/test/asan/TestCases/alloca_loop_unpoisoning.cc
@@ -15,6 +15,10 @@
# define alloca _alloca
#endif
+#if defined(__sun__) && defined(__svr4__)
+#include <alloca.h>
+#endif
+
void *top, *bot;
__attribute__((noinline)) void foo(int len) {
diff --git a/test/asan/TestCases/alloca_vla_interact.cc b/test/asan/TestCases/alloca_vla_interact.cc
index 4717c9d977ed..92b0afafc8db 100644
--- a/test/asan/TestCases/alloca_vla_interact.cc
+++ b/test/asan/TestCases/alloca_vla_interact.cc
@@ -15,6 +15,10 @@
# define alloca _alloca
#endif
+#if defined(__sun__) && defined(__svr4__)
+#include <alloca.h>
+#endif
+
#define RZ 32
__attribute__((noinline)) void foo(int len) {
diff --git a/test/asan/TestCases/allocator_returns_null.cc b/test/asan/TestCases/allocator_returns_null.cc
deleted file mode 100644
index 8ce002f04d61..000000000000
--- a/test/asan/TestCases/allocator_returns_null.cc
+++ /dev/null
@@ -1,131 +0,0 @@
-// Test the behavior of malloc/calloc/realloc/new when the allocation size is
-// more than ASan allocator's max allowed one.
-// By default (allocator_may_return_null=0) the process should crash.
-// With allocator_may_return_null=1 the allocator should return 0, except the
-// operator new(), which should crash anyway (operator new(std::nothrow) should
-// return nullptr, indeed).
-//
-// RUN: %clangxx_asan -O0 %s -o %t
-// RUN: not %run %t malloc 2>&1 | FileCheck %s --check-prefix=CHECK-mCRASH
-// RUN: %env_asan_opts=allocator_may_return_null=0 not %run %t malloc 2>&1 \
-// RUN: | FileCheck %s --check-prefix=CHECK-mCRASH
-// RUN: %env_asan_opts=allocator_may_return_null=1 %run %t malloc 2>&1 \
-// RUN: | FileCheck %s --check-prefix=CHECK-mNULL
-// RUN: %env_asan_opts=allocator_may_return_null=0 not %run %t calloc 2>&1 \
-// RUN: | FileCheck %s --check-prefix=CHECK-cCRASH
-// RUN: %env_asan_opts=allocator_may_return_null=1 %run %t calloc 2>&1 \
-// RUN: | FileCheck %s --check-prefix=CHECK-cNULL
-// RUN: %env_asan_opts=allocator_may_return_null=0 not %run %t calloc-overflow 2>&1 \
-// RUN: | FileCheck %s --check-prefix=CHECK-coCRASH
-// RUN: %env_asan_opts=allocator_may_return_null=1 %run %t calloc-overflow 2>&1 \
-// RUN: | FileCheck %s --check-prefix=CHECK-coNULL
-// RUN: %env_asan_opts=allocator_may_return_null=0 not %run %t realloc 2>&1 \
-// RUN: | FileCheck %s --check-prefix=CHECK-rCRASH
-// RUN: %env_asan_opts=allocator_may_return_null=1 %run %t realloc 2>&1 \
-// RUN: | FileCheck %s --check-prefix=CHECK-rNULL
-// RUN: %env_asan_opts=allocator_may_return_null=0 not %run %t realloc-after-malloc 2>&1 \
-// RUN: | FileCheck %s --check-prefix=CHECK-mrCRASH
-// RUN: %env_asan_opts=allocator_may_return_null=1 %run %t realloc-after-malloc 2>&1 \
-// RUN: | FileCheck %s --check-prefix=CHECK-mrNULL
-// RUN: %env_asan_opts=allocator_may_return_null=0 not %run %t new 2>&1 \
-// RUN: | FileCheck %s --check-prefix=CHECK-nCRASH
-// RUN: %env_asan_opts=allocator_may_return_null=1 not %run %t new 2>&1 \
-// RUN: | FileCheck %s --check-prefix=CHECK-nCRASH
-// RUN: %env_asan_opts=allocator_may_return_null=0 not %run %t new-nothrow 2>&1 \
-// RUN: | FileCheck %s --check-prefix=CHECK-nnCRASH
-// RUN: %env_asan_opts=allocator_may_return_null=1 %run %t new-nothrow 2>&1 \
-// RUN: | FileCheck %s --check-prefix=CHECK-nnNULL
-
-// UNSUPPORTED: win32
-
-#include <assert.h>
-#include <errno.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <limits>
-#include <new>
-
-int main(int argc, char **argv) {
- // Disable stderr buffering. Needed on Windows.
- setvbuf(stderr, NULL, _IONBF, 0);
-
- assert(argc == 2);
- const char *action = argv[1];
- fprintf(stderr, "%s:\n", action);
-
- static const size_t kMaxAllowedMallocSizePlusOne =
-#if __LP64__ || defined(_WIN64)
- (1ULL << 40) + 1;
-#else
- (3UL << 30) + 1;
-#endif
-
- void *x = 0;
- if (!strcmp(action, "malloc")) {
- x = malloc(kMaxAllowedMallocSizePlusOne);
- } else if (!strcmp(action, "calloc")) {
- x = calloc((kMaxAllowedMallocSizePlusOne / 4) + 1, 4);
- } else if (!strcmp(action, "calloc-overflow")) {
- volatile size_t kMaxSizeT = std::numeric_limits<size_t>::max();
- size_t kArraySize = 4096;
- volatile size_t kArraySize2 = kMaxSizeT / kArraySize + 10;
- x = calloc(kArraySize, kArraySize2);
- } else if (!strcmp(action, "realloc")) {
- x = realloc(0, kMaxAllowedMallocSizePlusOne);
- } else if (!strcmp(action, "realloc-after-malloc")) {
- char *t = (char*)malloc(100);
- *t = 42;
- x = realloc(t, kMaxAllowedMallocSizePlusOne);
- assert(*t == 42);
- free(t);
- } else if (!strcmp(action, "new")) {
- x = operator new(kMaxAllowedMallocSizePlusOne);
- } else if (!strcmp(action, "new-nothrow")) {
- x = operator new(kMaxAllowedMallocSizePlusOne, std::nothrow);
- } else {
- assert(0);
- }
-
- fprintf(stderr, "errno: %d\n", errno);
-
- // The NULL pointer is printed differently on different systems, while (long)0
- // is always the same.
- fprintf(stderr, "x: %lx\n", (long)x);
- free(x);
-
- return x != 0;
-}
-
-// CHECK-mCRASH: malloc:
-// CHECK-mCRASH: AddressSanitizer's allocator is terminating the process
-// CHECK-cCRASH: calloc:
-// CHECK-cCRASH: AddressSanitizer's allocator is terminating the process
-// CHECK-coCRASH: calloc-overflow:
-// CHECK-coCRASH: AddressSanitizer's allocator is terminating the process
-// CHECK-rCRASH: realloc:
-// CHECK-rCRASH: AddressSanitizer's allocator is terminating the process
-// CHECK-mrCRASH: realloc-after-malloc:
-// CHECK-mrCRASH: AddressSanitizer's allocator is terminating the process
-// CHECK-nCRASH: new:
-// CHECK-nCRASH: AddressSanitizer's allocator is terminating the process
-// CHECK-nnCRASH: new-nothrow:
-// CHECK-nnCRASH: AddressSanitizer's allocator is terminating the process
-
-// CHECK-mNULL: malloc:
-// CHECK-mNULL: errno: 12
-// CHECK-mNULL: x: 0
-// CHECK-cNULL: calloc:
-// CHECK-cNULL: errno: 12
-// CHECK-cNULL: x: 0
-// CHECK-coNULL: calloc-overflow:
-// CHECK-coNULL: errno: 12
-// CHECK-coNULL: x: 0
-// CHECK-rNULL: realloc:
-// CHECK-rNULL: errno: 12
-// CHECK-rNULL: x: 0
-// CHECK-mrNULL: realloc-after-malloc:
-// CHECK-mrNULL: errno: 12
-// CHECK-mrNULL: x: 0
-// CHECK-nnNULL: new-nothrow:
-// CHECK-nnNULL: x: 0
diff --git a/test/asan/TestCases/calloc-overflow.cc b/test/asan/TestCases/calloc-overflow.cc
new file mode 100644
index 000000000000..74582378fd2f
--- /dev/null
+++ b/test/asan/TestCases/calloc-overflow.cc
@@ -0,0 +1,21 @@
+// RUN: %clangxx_asan -O0 %s -o %t
+// RUN: %env_asan_opts=allocator_may_return_null=0 not %run %t 2>&1 | FileCheck %s
+// RUN: %env_asan_opts=allocator_may_return_null=1 %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-NULL
+
+// REQUIRES: stable-runtime
+
+#include <stdio.h>
+#include <stdlib.h>
+
+int main() {
+ void *p = calloc(-1, 1000);
+ // CHECK: {{ERROR: AddressSanitizer: calloc parameters overflow: count \* size \(.* \* 1000\) cannot be represented in type size_t}}
+ // CHECK: {{#0 0x.* in .*calloc}}
+ // CHECK: {{#1 0x.* in main .*calloc-overflow.cc:}}[[@LINE-3]]
+ // CHECK: SUMMARY: AddressSanitizer: calloc-overflow
+
+ printf("calloc returned: %zu\n", (size_t)p);
+ // CHECK-NULL: calloc returned: 0
+
+ return 0;
+}
diff --git a/test/asan/TestCases/coverage-and-lsan.cc b/test/asan/TestCases/coverage-and-lsan.cc
index 591b4e93fac7..60851dabb6b7 100644
--- a/test/asan/TestCases/coverage-and-lsan.cc
+++ b/test/asan/TestCases/coverage-and-lsan.cc
@@ -2,11 +2,11 @@
//
// RUN: %clangxx_asan -fsanitize-coverage=func,trace-pc-guard %s -o %t
//
-// RUN: rm -rf %T/coverage-and-lsan
+// RUN: rm -rf %t-dir
//
-// RUN: mkdir -p %T/coverage-and-lsan/normal
-// RUN: %env_asan_opts=coverage=1:coverage_dir=%T/coverage-and-lsan:verbosity=1 not %run %t 2>&1 | FileCheck %s
-// RUN: %sancov print %T/coverage-and-lsan/*.sancov 2>&1
+// RUN: mkdir -p %t-dir
+// RUN: %env_asan_opts=coverage=1:coverage_dir=%t-dir:verbosity=1 not %run %t 2>&1 | FileCheck %s
+// RUN: %sancov print %t-dir/*.sancov 2>&1
//
// REQUIRES: leak-detection
diff --git a/test/asan/TestCases/coverage-disabled.cc b/test/asan/TestCases/coverage-disabled.cc
index b225035ee4ca..46a822dff08c 100644
--- a/test/asan/TestCases/coverage-disabled.cc
+++ b/test/asan/TestCases/coverage-disabled.cc
@@ -1,12 +1,12 @@
// Test that no data is collected without a runtime flag.
//
-// RUN: %clangxx_asan -fsanitize-coverage=func %s -o %t
+// RUN: rm -rf %t-dir
+// RUN: mkdir -p %t-dir
//
-// RUN: rm -rf %T/coverage-disabled
+// RUN: %clangxx_asan -fsanitize-coverage=func %s -o %t
//
-// RUN: mkdir -p %T/coverage-disabled/normal
-// RUN: %env_asan_opts=coverage_direct=0:coverage_dir='"%T/coverage-disabled/normal"':verbosity=1 %run %t
-// RUN: not %sancov print %T/coverage-disabled/normal/*.sancov 2>&1
+// RUN: %env_asan_opts=coverage_direct=0:coverage_dir='"%t-dir"':verbosity=1 %run %t
+// RUN: not %sancov print %t-dir/*.sancov 2>&1
//
// UNSUPPORTED: android
diff --git a/test/asan/TestCases/debug_double_free.cc b/test/asan/TestCases/debug_double_free.cc
index c3699b9762d8..44c820b638d6 100644
--- a/test/asan/TestCases/debug_double_free.cc
+++ b/test/asan/TestCases/debug_double_free.cc
@@ -15,6 +15,9 @@
# else
# define PTR_FMT "0x%08x"
# endif
+// Solaris libc omits the leading 0x.
+#elif defined(__sun__) && defined(__svr4__)
+# define PTR_FMT "0x%p"
#else
# define PTR_FMT "%p"
#endif
diff --git a/test/asan/TestCases/debug_ppc64_mapping.cc b/test/asan/TestCases/debug_ppc64_mapping.cc
index 0db7956693c5..a67804023c0c 100644
--- a/test/asan/TestCases/debug_ppc64_mapping.cc
+++ b/test/asan/TestCases/debug_ppc64_mapping.cc
@@ -6,9 +6,9 @@
#include <stdio.h>
int main() {
-// CHECK-PPC64: || `[{{0x180|0x0a0|0x040}}000000000, {{0x3ff|0x0ff}}fffffffff]` || HighMem ||
-// CHECK-PPC64: || `[{{0x130|0x034|0x028}}000000000, {{0x17f|0x09f|0x03f}}fffffffff]` || HighShadow ||
-// CHECK-PPC64: || `[{{0x120|0x024|0x024}}000000000, {{0x12f|0x033|0x027}}fffffffff]` || ShadowGap ||
+// CHECK-PPC64: || `[{{0x200|0x180|0x0a0|0x040}}000000000, {{0x7ff|0x3ff|0x0ff}}fffffffff]` || HighMem ||
+// CHECK-PPC64: || `[{{0x140|0x130|0x034|0x028}}000000000, {{0x1ff|0x17f|0x09f|0x03f}}fffffffff]` || HighShadow ||
+// CHECK-PPC64: || `[{{0x120|0x024|0x024}}000000000, {{0x12f|0x13f|0x033|0x027}}fffffffff]` || ShadowGap ||
// CHECK-PPC64: || `[{{0x100|0x020}}000000000, {{0x11f|0x023}}fffffffff]` || LowShadow ||
// CHECK-PPC64: || `[0x000000000000, {{0x0ff|0x01f}}fffffffff]` || LowMem ||
//
@@ -19,8 +19,16 @@ int main() {
}
/*
- * Three different signatures noted.
-Newer kernel: (starting with kernel version 4.?)
+ * Several different signatures noted.
+
+Newer kernel: (Fedora starting with kernel version 4.?)
+|| `[0x200000000000, 0x7fffffffffff]` || HighMem ||
+|| `[0x140000000000, 0x1fffffffffff]` || HighShadow ||
+|| `[0x120000000000, 0x13ffffffffff]` || ShadowGap ||
+|| `[0x100000000000, 0x11ffffffffff]` || LowShadow ||
+|| `[0x000000000000, 0x0fffffffffff]` || LowMem ||
+
+Newer kernel: (Ubuntu starting with kernel version 4.?)
|| `[0x180000000000, 0x3fffffffffff]` || HighMem ||
|| `[0x130000000000, 0x17ffffffffff]` || HighShadow ||
|| `[0x120000000000, 0x12ffffffffff]` || ShadowGap ||
diff --git a/test/asan/TestCases/debug_report.cc b/test/asan/TestCases/debug_report.cc
index 34bc06eba62c..14bb70e9f593 100644
--- a/test/asan/TestCases/debug_report.cc
+++ b/test/asan/TestCases/debug_report.cc
@@ -30,6 +30,9 @@ int main() {
# else
# define PTR_FMT "0x%08x"
# endif
+// Solaris libc omits the leading 0x.
+#elif defined(__sun__) && defined(__svr4__)
+# define PTR_FMT "0x%p"
#else
# define PTR_FMT "%p"
#endif
diff --git a/test/asan/TestCases/handle_noreturn_bug.cc b/test/asan/TestCases/handle_noreturn_bug.cc
new file mode 100644
index 000000000000..8c3c66a423d5
--- /dev/null
+++ b/test/asan/TestCases/handle_noreturn_bug.cc
@@ -0,0 +1,13 @@
+// Regression test: __asan_handle_no_return should unpoison stack even with poison_heap=0.
+// RUN: %clangxx_asan -O0 %s -o %t && \
+// RUN: %env_asan_opts=poison_heap=1 %run %t && \
+// RUN: %env_asan_opts=poison_heap=0 %run %t
+
+#include <sanitizer/asan_interface.h>
+
+int main(int argc, char **argv) {
+ int x[2];
+ int * volatile p = &x[0];
+ __asan_handle_no_return();
+ int volatile z = p[2];
+}
diff --git a/test/asan/TestCases/heavy_uar_test.cc b/test/asan/TestCases/heavy_uar_test.cc
index 9ad29f079d92..94df0cefc73b 100644
--- a/test/asan/TestCases/heavy_uar_test.cc
+++ b/test/asan/TestCases/heavy_uar_test.cc
@@ -1,12 +1,12 @@
// RUN: %clangxx_asan -O0 %s -o %t && %env_asan_opts=detect_stack_use_after_return=1 not %run %t 2>&1 | FileCheck %s
// RUN: %clangxx_asan -O2 %s -o %t && %env_asan_opts=detect_stack_use_after_return=1 not %run %t 2>&1 | FileCheck %s
-// XFAIL: arm-linux-gnueabi,win32
+// XFAIL: win32
// FIXME: Fix this test under GCC.
// REQUIRES: Clang
-// FIXME: Fix this test for dynamic runtime on armhf-linux.
-// UNSUPPORTED: armhf-linux && asan-dynamic-runtime
+// FIXME: Fix this test for dynamic runtime on arm linux.
+// UNSUPPORTED: (arm-linux || armhf-linux) && asan-dynamic-runtime
// UNSUPPORTED: ios
diff --git a/test/asan/TestCases/intercept-rethrow-exception.cc b/test/asan/TestCases/intercept-rethrow-exception.cc
new file mode 100644
index 000000000000..fa9ea7d3b09e
--- /dev/null
+++ b/test/asan/TestCases/intercept-rethrow-exception.cc
@@ -0,0 +1,64 @@
+// Regression test for
+// https://bugs.llvm.org/show_bug.cgi?id=32434
+
+// RUN: %clangxx_asan -O0 %s -o %t
+// RUN: %run %t
+
+#include <assert.h>
+#include <exception>
+#include <sanitizer/asan_interface.h>
+
+namespace {
+
+// Not instrumented because std::rethrow_exception is a [[noreturn]] function,
+// for which the compiler would emit a call to __asan_handle_no_return which
+// unpoisons the stack.
+// We emulate here some code not compiled with asan. This function is not
+// [[noreturn]] because the scenario we're emulating doesn't always throw. If it
+// were [[noreturn]], the calling code would emit a call to
+// __asan_handle_no_return.
+void __attribute__((no_sanitize("address")))
+uninstrumented_rethrow_exception(std::exception_ptr const &exc_ptr) {
+ std::rethrow_exception(exc_ptr);
+}
+
+char *poisoned1;
+char *poisoned2;
+
+// Create redzones for stack variables in shadow memory and call
+// std::rethrow_exception which should unpoison the entire stack.
+void create_redzones_and_throw(std::exception_ptr const &exc_ptr) {
+ char a[100];
+ poisoned1 = a - 1;
+ poisoned2 = a + sizeof(a);
+ assert(__asan_address_is_poisoned(poisoned1));
+ assert(__asan_address_is_poisoned(poisoned2));
+ uninstrumented_rethrow_exception(exc_ptr);
+}
+
+} // namespace
+
+// Check that std::rethrow_exception is intercepted by asan and the interception
+// unpoisons the stack.
+// If std::rethrow_exception is NOT intercepted, then calls to this function
+// from instrumented code will still unpoison the stack because
+// std::rethrow_exception is a [[noreturn]] function and any [[noreturn]]
+// function call will be instrumented with __asan_handle_no_return.
+// However, calls to std::rethrow_exception from UNinstrumented code will not
+// unpoison the stack, so we need to intercept std::rethrow_exception to
+// unpoison the stack.
+int main() {
+ // In some implementations of std::make_exception_ptr, e.g. libstdc++ prior to
+ // gcc 7, this function calls __cxa_throw. The __cxa_throw is intercepted by
+ // asan to unpoison the entire stack; since this test essentially tests that
+ // the stack is unpoisoned by a call to std::rethrow_exception, we need to
+ // generate the exception_ptr BEFORE we have the local variables poison the
+ // stack.
+ std::exception_ptr my_exception_ptr = std::make_exception_ptr("up");
+
+ try {
+ create_redzones_and_throw(my_exception_ptr);
+ } catch(char const *) {
+ assert(!__asan_region_is_poisoned(poisoned1, poisoned2 - poisoned1 + 1));
+ }
+}
diff --git a/test/asan/TestCases/invalid-pointer-pairs-compare-errors.cc b/test/asan/TestCases/invalid-pointer-pairs-compare-errors.cc
index 82f63359ead7..0690d40d2261 100644
--- a/test/asan/TestCases/invalid-pointer-pairs-compare-errors.cc
+++ b/test/asan/TestCases/invalid-pointer-pairs-compare-errors.cc
@@ -1,6 +1,6 @@
// RUN: %clangxx_asan -O0 %s -o %t -mllvm -asan-detect-invalid-pointer-pair
-// RUN: %env_asan_opts=detect_invalid_pointer_pairs=1:halt_on_error=0 %run %t 2>&1 | FileCheck %s
+// RUN: %env_asan_opts=detect_invalid_pointer_pairs=2:halt_on_error=0 %run %t 2>&1 | FileCheck %s
#include <assert.h>
#include <stdlib.h>
@@ -10,8 +10,12 @@ int foo(char *p, char *q) {
}
char global1[100] = {}, global2[100] = {};
+char __attribute__((used)) smallest_global[5] = {};
char small_global[7] = {};
+char __attribute__((used)) little_global[10] = {};
+char __attribute__((used)) medium_global[4000] = {};
char large_global[5000] = {};
+char __attribute__((used)) largest_global[6000] = {};
int main() {
// Heap allocated memory.
diff --git a/test/asan/TestCases/invalid-pointer-pairs-compare-null.cc b/test/asan/TestCases/invalid-pointer-pairs-compare-null.cc
new file mode 100644
index 000000000000..9f7f7b6f439d
--- /dev/null
+++ b/test/asan/TestCases/invalid-pointer-pairs-compare-null.cc
@@ -0,0 +1,42 @@
+// RUN: %clangxx_asan -O0 %s -o %t -mllvm -asan-detect-invalid-pointer-pair
+
+// RUN: %env_asan_opts=detect_invalid_pointer_pairs=1 %run %t
+
+#include <assert.h>
+#include <stdlib.h>
+
+int foo(char *p, char *q) {
+ return p <= q;
+}
+
+char global[8192] = {};
+char small_global[7] = {};
+
+int main() {
+ // Heap allocated memory.
+ char *p = (char *)malloc(42);
+ int r = foo(p, NULL);
+ free(p);
+
+ p = (char *)malloc(1024);
+ foo(NULL, p);
+ free(p);
+
+ p = (char *)malloc(4096);
+ foo(p, NULL);
+ free(p);
+
+ // Global variable.
+ foo(&global[0], NULL);
+ foo(&global[1000], NULL);
+
+ p = &small_global[0];
+ foo(p, NULL);
+
+ // Stack variable.
+ char stack[10000];
+ foo(&stack[0], NULL);
+ foo(NULL, &stack[9000]);
+
+ return 0;
+}
diff --git a/test/asan/TestCases/invalid-pointer-pairs-compare-success.cc b/test/asan/TestCases/invalid-pointer-pairs-compare-success.cc
index 565d39088340..d0d92265f002 100644
--- a/test/asan/TestCases/invalid-pointer-pairs-compare-success.cc
+++ b/test/asan/TestCases/invalid-pointer-pairs-compare-success.cc
@@ -1,6 +1,6 @@
// RUN: %clangxx_asan -O0 %s -o %t -mllvm -asan-detect-invalid-pointer-pair
-// RUN: %env_asan_opts=detect_invalid_pointer_pairs=1 %run %t
+// RUN: %env_asan_opts=detect_invalid_pointer_pairs=2 %run %t
#include <assert.h>
#include <stdlib.h>
diff --git a/test/asan/TestCases/invalid-pointer-pairs-subtract-errors.cc b/test/asan/TestCases/invalid-pointer-pairs-subtract-errors.cc
index 546f61f8184d..20aaebeb48e0 100644
--- a/test/asan/TestCases/invalid-pointer-pairs-subtract-errors.cc
+++ b/test/asan/TestCases/invalid-pointer-pairs-subtract-errors.cc
@@ -1,6 +1,6 @@
// RUN: %clangxx_asan -O0 %s -o %t -mllvm -asan-detect-invalid-pointer-pair
-// RUN: %env_asan_opts=detect_invalid_pointer_pairs=1:halt_on_error=0 %run %t 2>&1 | FileCheck %s
+// RUN: %env_asan_opts=detect_invalid_pointer_pairs=2:halt_on_error=0 %run %t 2>&1 | FileCheck %s
#include <assert.h>
#include <stdlib.h>
diff --git a/test/asan/TestCases/invalid-pointer-pairs-subtract-success.cc b/test/asan/TestCases/invalid-pointer-pairs-subtract-success.cc
index 4ce48424899d..7ea120ed5c70 100644
--- a/test/asan/TestCases/invalid-pointer-pairs-subtract-success.cc
+++ b/test/asan/TestCases/invalid-pointer-pairs-subtract-success.cc
@@ -1,12 +1,12 @@
// RUN: %clangxx_asan -O0 %s -o %t -mllvm -asan-detect-invalid-pointer-pair
-// RUN: %env_asan_opts=detect_invalid_pointer_pairs=1 %run %t
+// RUN: %env_asan_opts=detect_invalid_pointer_pairs=2 %run %t
#include <assert.h>
#include <stdlib.h>
int bar(char *p, char *q) {
- return p <= q;
+ return p - q;
}
char global[10000] = {};
diff --git a/test/asan/TestCases/malloc-no-intercept.c b/test/asan/TestCases/malloc-no-intercept.c
index c1442e6cfa90..ca98febed0fb 100644
--- a/test/asan/TestCases/malloc-no-intercept.c
+++ b/test/asan/TestCases/malloc-no-intercept.c
@@ -10,6 +10,11 @@
// Conflicts with BIONIC declarations.
// UNSUPPORTED: android
+// Inhibit conflicting declaration of memalign on Solaris.
+#if defined(__sun__) && defined(__svr4__)
+#undef __EXTENSIONS__
+#endif
+
#include <stdlib.h>
// For glibc, cause link failures by referencing a nonexistent function.
diff --git a/test/asan/TestCases/malloc-size-too-big.cc b/test/asan/TestCases/malloc-size-too-big.cc
new file mode 100644
index 000000000000..f41b7ef75d71
--- /dev/null
+++ b/test/asan/TestCases/malloc-size-too-big.cc
@@ -0,0 +1,28 @@
+// RUN: %clangxx_asan -O0 %s -o %t
+// RUN: %env_asan_opts=allocator_may_return_null=0 not %run %t 2>&1 | FileCheck %s
+// RUN: %env_asan_opts=allocator_may_return_null=1 %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-NULL
+
+// REQUIRES: stable-runtime
+
+#include <stdio.h>
+#include <stdlib.h>
+
+static const size_t kMaxAllowedMallocSizePlusOne =
+#if __LP64__ || defined(_WIN64)
+ (1ULL << 40) + 1;
+#else
+ (3UL << 30) + 1;
+#endif
+
+int main() {
+ void *p = malloc(kMaxAllowedMallocSizePlusOne);
+ // CHECK: {{ERROR: AddressSanitizer: requested allocation size .* \(.* after adjustments for alignment, red zones etc\.\) exceeds maximum supported size}}
+ // CHECK: {{#0 0x.* in .*malloc}}
+ // CHECK: {{#1 0x.* in main .*malloc-size-too-big.cc:}}[[@LINE-3]]
+ // CHECK: SUMMARY: AddressSanitizer: allocation-size-too-big
+
+ printf("malloc returned: %zu\n", (size_t)p);
+ // CHECK-NULL: malloc returned: 0
+
+ return 0;
+}
diff --git a/test/asan/TestCases/non-executable-pc.cpp b/test/asan/TestCases/non-executable-pc.cpp
index 6ef40540b0ac..60e900b87160 100644
--- a/test/asan/TestCases/non-executable-pc.cpp
+++ b/test/asan/TestCases/non-executable-pc.cpp
@@ -3,7 +3,10 @@
// RUN: not %run %t n 2>&1 | FileCheck %s -check-prefix=CHECK -check-prefix=NON_EXEC
// Not every OS lists every memory region in MemoryMappingLayout.
-// REQUIRES: linux || freebsd || netbsd
+// This is limited to x86_64 because some architectures (e.g. the s390 before
+// the z14) don't support NX mappings and others like PowerPC use function
+// descriptors.
+// REQUIRES: x86-target-arch && (linux || freebsd || netbsd)
#include <assert.h>
@@ -20,12 +23,6 @@ int main(int argc, char **argv) {
}
func();
- // x86 reports the SEGV with both address=X and pc=X.
- // On PowerPC64 ELFv1, the pointer is taken to be a function-descriptor
- // pointer out of which three 64-bit quantities are read. This will SEGV, but
- // the compiler is free to choose the order. As a result, the address is
- // either X, X+0x8 or X+0x10. The pc is still in main() because it has not
- // actually made the call when the faulting access occurs.
// CHECK: DEADLYSIGNAL
// CHECK: {{AddressSanitizer: (SEGV|access-violation).*(address|pc) }}
// NON_EXEC: PC is at a non-executable region. Maybe a wild jump?
diff --git a/test/asan/TestCases/null_deref.cc b/test/asan/TestCases/null_deref.cc
index 04576b40eb24..222c526fdc13 100644
--- a/test/asan/TestCases/null_deref.cc
+++ b/test/asan/TestCases/null_deref.cc
@@ -15,10 +15,10 @@ void NullDeref(int *ptr) {
ptr[10]++; // BOOM
// atos on Mac cannot extract the symbol name correctly. Also, on FreeBSD 9.2
// the demangling function rejects local names with 'L' in front of them.
- // CHECK: {{ #0 0x.* in .*NullDeref.*null_deref.cc:}}[[@LINE-3]]
+ // CHECK: {{ #0 0x.* in .*NullDeref.*null_deref.cc}}
}
int main() {
NullDeref((int*)0);
- // CHECK: {{ #1 0x.* in main.*null_deref.cc:}}[[@LINE-1]]
+ // CHECK: {{ #1 0x.* in main.*null_deref.cc}}
// CHECK: AddressSanitizer can not provide additional info.
}
diff --git a/test/asan/TestCases/printf-4.c b/test/asan/TestCases/printf-4.c
index 5a883fe99efd..70f4073cc496 100644
--- a/test/asan/TestCases/printf-4.c
+++ b/test/asan/TestCases/printf-4.c
@@ -2,8 +2,9 @@
// RUN: %env_asan_opts=check_printf=1 not %run %t 2>&1 | FileCheck --check-prefix=CHECK-ON %s
// RUN: not %run %t 2>&1 | FileCheck --check-prefix=CHECK-ON %s
-// FIXME: sprintf is not intercepted on Windows yet.
-// XFAIL: win32
+// FIXME: sprintf is not intercepted on Windows yet. But this test can
+// pass if sprintf calls memmove, which is intercepted, so we can't XFAIL it.
+// UNSUPPORTED: win32
#include <stdio.h>
int main() {
diff --git a/test/asan/TestCases/scariness_score_test.cc b/test/asan/TestCases/scariness_score_test.cc
index 171bea9ee191..fb174eb52b2b 100644
--- a/test/asan/TestCases/scariness_score_test.cc
+++ b/test/asan/TestCases/scariness_score_test.cc
@@ -115,7 +115,7 @@ void DoubleFree() {
}
void StackOverflow(int Idx) {
- int some_stack[10000];
+ int some_stack[256];
static volatile int *x;
x = &some_stack[0];
if (Idx > 0)
diff --git a/test/asan/TestCases/strcat-overlap.cc b/test/asan/TestCases/strcat-overlap.cc
new file mode 100644
index 000000000000..89991fbd7881
--- /dev/null
+++ b/test/asan/TestCases/strcat-overlap.cc
@@ -0,0 +1,54 @@
+// RUN: %clangxx_asan -O0 %s -o %t
+// RUN: not %run %t 2>&1 | FileCheck %s
+// RUN: echo "interceptor_via_fun:bad_function" > %t.supp
+// RUN: %env_asan_opts=suppressions='"%t.supp"' %run %t
+// RUN: echo "interceptor_name:strcat" > %t.supp
+// RUN: %env_asan_opts=suppressions='"%t.supp"' %run %t
+//
+// RUN: %clangxx_asan -O1 %s -o %t
+// RUN: not %run %t 2>&1 | FileCheck %s
+// RUN: echo "interceptor_via_fun:bad_function" > %t.supp
+// RUN: %env_asan_opts=suppressions='"%t.supp"' %run %t
+// RUN: echo "interceptor_name:strcat" > %t.supp
+// RUN: %env_asan_opts=suppressions='"%t.supp"' %run %t
+//
+// RUN: %clangxx_asan -O2 %s -o %t
+// RUN: not %run %t 2>&1 | FileCheck %s
+// RUN: echo "interceptor_via_fun:bad_function" > %t.supp
+// RUN: %env_asan_opts=suppressions='"%t.supp"' %run %t
+// RUN: echo "interceptor_name:strcat" > %t.supp
+// RUN: %env_asan_opts=suppressions='"%t.supp"' %run %t
+//
+// RUN: %clangxx_asan -O3 %s -o %t
+// RUN: not %run %t 2>&1 | FileCheck %s
+// RUN: echo "interceptor_via_fun:bad_function" > %t.supp
+// RUN: %env_asan_opts=suppressions='"%t.supp"' %run %t
+// RUN: echo "interceptor_name:strcat" > %t.supp
+// RUN: %env_asan_opts=suppressions='"%t.supp"' %run %t
+
+// This test when run with suppressions invokes undefined
+// behavior which can cause all sorts of bad things to happen
+// depending on how strcat() is implemented. For now only run
+// on platforms where we know the test passes.
+// REQUIRES: x86_64h-darwin || x86_64-darwin || i386-darwin || x86_64-linux || i386-linux
+// UNSUPPORTED: win32
+// UNSUPPORTED: android
+
+#include <string.h>
+
+
+// Don't inline function otherwise stacktrace changes.
+__attribute__((noinline)) void bad_function() {
+ char buffer[] = "hello\0XXX";
+ // CHECK: strcat-param-overlap: memory ranges
+ // CHECK: [{{0x.*,[ ]*0x.*}}) and [{{0x.*,[ ]*0x.*}}) overlap
+ // CHECK: {{#0 0x.* in .*strcat}}
+ // CHECK: {{#1 0x.* in bad_function.*strcat-overlap.cc:}}[[@LINE+2]]
+ // CHECK: {{#2 0x.* in main .*strcat-overlap.cc:}}[[@LINE+5]]
+ strcat(buffer, buffer + 1); // BOOM
+}
+
+int main(int argc, char **argv) {
+ bad_function();
+ return 0;
+}
diff --git a/test/asan/TestCases/strcpy-overlap.cc b/test/asan/TestCases/strcpy-overlap.cc
new file mode 100644
index 000000000000..53b77e13d91e
--- /dev/null
+++ b/test/asan/TestCases/strcpy-overlap.cc
@@ -0,0 +1,48 @@
+// RUN: %clangxx_asan -O0 %s -o %t
+// RUN: not %run %t 2>&1 | FileCheck %s
+// RUN: echo "interceptor_via_fun:bad_function" > %t.supp
+// RUN: %env_asan_opts=suppressions='"%t.supp"' %run %t
+// RUN: echo "interceptor_name:strcpy" > %t.supp
+// RUN: %env_asan_opts=suppressions='"%t.supp"' %run %t
+//
+// RUN: %clangxx_asan -O1 %s -o %t
+// RUN: not %run %t 2>&1 | FileCheck %s
+// RUN: echo "interceptor_via_fun:bad_function" > %t.supp
+// RUN: %env_asan_opts=suppressions='"%t.supp"' %run %t
+// RUN: echo "interceptor_name:strcpy" > %t.supp
+// RUN: %env_asan_opts=suppressions='"%t.supp"' %run %t
+//
+// RUN: %clangxx_asan -O2 %s -o %t
+// RUN: not %run %t 2>&1 | FileCheck %s
+// RUN: echo "interceptor_via_fun:bad_function" > %t.supp
+// RUN: %env_asan_opts=suppressions='"%t.supp"' %run %t
+// RUN: echo "interceptor_name:strcpy" > %t.supp
+// RUN: %env_asan_opts=suppressions='"%t.supp"' %run %t
+//
+// RUN: %clangxx_asan -O3 %s -o %t
+// RUN: not %run %t 2>&1 | FileCheck %s
+// RUN: echo "interceptor_via_fun:bad_function" > %t.supp
+// RUN: %env_asan_opts=suppressions='"%t.supp"' %run %t
+// RUN: echo "interceptor_name:strcpy" > %t.supp
+// RUN: %env_asan_opts=suppressions='"%t.supp"' %run %t
+
+// UNSUPPORTED: android
+
+#include <string.h>
+
+
+// Don't inline function otherwise stacktrace changes.
+__attribute__((noinline)) void bad_function() {
+ char buffer[] = "hello";
+ // CHECK: strcpy-param-overlap: memory ranges
+ // CHECK: [{{0x.*,[ ]*0x.*}}) and [{{0x.*,[ ]*0x.*}}) overlap
+ // CHECK: {{#0 0x.* in .*strcpy}}
+ // CHECK: {{#1 0x.* in bad_function.*strcpy-overlap.cc:}}[[@LINE+2]]
+ // CHECK: {{#2 0x.* in main .*strcpy-overlap.cc:}}[[@LINE+5]]
+ strcpy(buffer, buffer + 1); // BOOM
+}
+
+int main(int argc, char **argv) {
+ bad_function();
+ return 0;
+}
diff --git a/test/asan/TestCases/strdup_oob_test.cc b/test/asan/TestCases/strdup_oob_test.cc
index 60c5ef12a473..e251dfcb4361 100644
--- a/test/asan/TestCases/strdup_oob_test.cc
+++ b/test/asan/TestCases/strdup_oob_test.cc
@@ -7,7 +7,7 @@
// RUN: %clangxx_asan -O3 -xc %s -o %t && not %run %t 2>&1 | FileCheck %s
// Unwind problem on arm: "main" is missing from the allocation stack trace.
-// UNSUPPORTED: armv7l-unknown-linux-gnueabihf
+// REQUIRES: (arm-target-arch || armhf-target-arch), fast-unwinder-works
// FIXME: We fail to intercept strdup with the dynamic WinASan RTL, so it's not
// in the stack trace.
diff --git a/test/asan/TestCases/strncat-overlap.cc b/test/asan/TestCases/strncat-overlap.cc
new file mode 100644
index 000000000000..959b783d263f
--- /dev/null
+++ b/test/asan/TestCases/strncat-overlap.cc
@@ -0,0 +1,48 @@
+// RUN: %clangxx_asan -O0 %s -o %t
+// RUN: not %run %t 2>&1 | FileCheck %s
+// RUN: echo "interceptor_via_fun:bad_function" > %t.supp
+// RUN: %env_asan_opts=suppressions='"%t.supp"' %run %t
+// RUN: echo "interceptor_name:strncat" > %t.supp
+// RUN: %env_asan_opts=suppressions='"%t.supp"' %run %t
+//
+// RUN: %clangxx_asan -O1 %s -o %t
+// RUN: not %run %t 2>&1 | FileCheck %s
+// RUN: echo "interceptor_via_fun:bad_function" > %t.supp
+// RUN: %env_asan_opts=suppressions='"%t.supp"' %run %t
+// RUN: echo "interceptor_name:strncat" > %t.supp
+// RUN: %env_asan_opts=suppressions='"%t.supp"' %run %t
+//
+// RUN: %clangxx_asan -O2 %s -o %t
+// RUN: not %run %t 2>&1 | FileCheck %s
+// RUN: echo "interceptor_via_fun:bad_function" > %t.supp
+// RUN: %env_asan_opts=suppressions='"%t.supp"' %run %t
+// RUN: echo "interceptor_name:strncat" > %t.supp
+// RUN: %env_asan_opts=suppressions='"%t.supp"' %run %t
+//
+// RUN: %clangxx_asan -O3 %s -o %t
+// RUN: not %run %t 2>&1 | FileCheck %s
+// RUN: echo "interceptor_via_fun:bad_function" > %t.supp
+// RUN: %env_asan_opts=suppressions='"%t.supp"' %run %t
+// RUN: echo "interceptor_name:strncat" > %t.supp
+// RUN: %env_asan_opts=suppressions='"%t.supp"' %run %t
+
+// UNSUPPORTED: android
+
+#include <string.h>
+
+
+// Don't inline function otherwise stacktrace changes.
+__attribute__((noinline)) void bad_function() {
+ char buffer[] = "hello\0XXX";
+ // CHECK: strncat-param-overlap: memory ranges
+ // CHECK: [{{0x.*,[ ]*0x.*}}) and [{{0x.*,[ ]*0x.*}}) overlap
+ // CHECK: {{#0 0x.* in .*strncat}}
+ // CHECK: {{#1 0x.* in bad_function.*strncat-overlap.cc:}}[[@LINE+2]]
+ // CHECK: {{#2 0x.* in main .*strncat-overlap.cc:}}[[@LINE+5]]
+ strncat(buffer, buffer + 1, 3); // BOOM
+}
+
+int main(int argc, char **argv) {
+ bad_function();
+ return 0;
+}
diff --git a/test/asan/TestCases/strncpy-overlap.cc b/test/asan/TestCases/strncpy-overlap.cc
new file mode 100644
index 000000000000..d7052cb49dc9
--- /dev/null
+++ b/test/asan/TestCases/strncpy-overlap.cc
@@ -0,0 +1,48 @@
+// RUN: %clangxx_asan -O0 %s -o %t
+// RUN: not %run %t 2>&1 | FileCheck %s
+// RUN: echo "interceptor_via_fun:bad_function" > %t.supp
+// RUN: %env_asan_opts=suppressions='"%t.supp"' %run %t
+// RUN: echo "interceptor_name:strncpy" > %t.supp
+// RUN: %env_asan_opts=suppressions='"%t.supp"' %run %t
+//
+// RUN: %clangxx_asan -O1 %s -o %t
+// RUN: not %run %t 2>&1 | FileCheck %s
+// RUN: echo "interceptor_via_fun:bad_function" > %t.supp
+// RUN: %env_asan_opts=suppressions='"%t.supp"' %run %t
+// RUN: echo "interceptor_name:strncpy" > %t.supp
+// RUN: %env_asan_opts=suppressions='"%t.supp"' %run %t
+//
+// RUN: %clangxx_asan -O2 %s -o %t
+// RUN: not %run %t 2>&1 | FileCheck %s
+// RUN: echo "interceptor_via_fun:bad_function" > %t.supp
+// RUN: %env_asan_opts=suppressions='"%t.supp"' %run %t
+// RUN: echo "interceptor_name:strncpy" > %t.supp
+// RUN: %env_asan_opts=suppressions='"%t.supp"' %run %t
+//
+// RUN: %clangxx_asan -O3 %s -o %t
+// RUN: not %run %t 2>&1 | FileCheck %s
+// RUN: echo "interceptor_via_fun:bad_function" > %t.supp
+// RUN: %env_asan_opts=suppressions='"%t.supp"' %run %t
+// RUN: echo "interceptor_name:strncpy" > %t.supp
+// RUN: %env_asan_opts=suppressions='"%t.supp"' %run %t
+
+// UNSUPPORTED: android
+
+#include <string.h>
+
+
+// Don't inline function otherwise stacktrace changes.
+__attribute__((noinline)) void bad_function() {
+ char buffer[] = "hello";
+ // CHECK: strncpy-param-overlap: memory ranges
+ // CHECK: [{{0x.*,[ ]*0x.*}}) and [{{0x.*,[ ]*0x.*}}) overlap
+ // CHECK: {{#0 0x.* in .*strncpy}}
+ // CHECK: {{#1 0x.* in bad_function.*strncpy-overlap.cc:}}[[@LINE+2]]
+ // CHECK: {{#2 0x.* in main .*strncpy-overlap.cc:}}[[@LINE+5]]
+ strncpy(buffer, buffer + 1, 5); // BOOM
+}
+
+int main(int argc, char **argv) {
+ bad_function();
+ return 0;
+}
diff --git a/test/asan/TestCases/suppressions-exec-relative-location.cc b/test/asan/TestCases/suppressions-exec-relative-location.cc
index d4e214d35a0e..d7497566a8c3 100644
--- a/test/asan/TestCases/suppressions-exec-relative-location.cc
+++ b/test/asan/TestCases/suppressions-exec-relative-location.cc
@@ -4,15 +4,15 @@
// If the executable is started from a different location, we should still
// find the suppression file located relative to the location of the executable.
-// RUN: rm -rf %T/suppressions-exec-relative-location
-// RUN: mkdir -p %T/suppressions-exec-relative-location
-// RUN: %clangxx_asan -O0 %s -o %T/suppressions-exec-relative-location/exec
+// RUN: rm -rf %t-dir
+// RUN: mkdir -p %t-dir
+// RUN: %clangxx_asan -O0 %s -o %t-dir/exec
// RUN: echo "interceptor_via_fun:crash_function" > \
-// RUN: %T/suppressions-exec-relative-location/supp.txt
+// RUN: %t-dir/supp.txt
// RUN: %env_asan_opts=suppressions='"supp.txt"' \
-// RUN: %run %T/suppressions-exec-relative-location/exec 2>&1 | \
+// RUN: %run %t-dir/exec 2>&1 | \
// RUN: FileCheck --check-prefix=CHECK-IGNORE %s
-// RUN: rm -rf %T/suppressions-exec-relative-location
+// RUN: rm -rf %t-dir
// If the wrong absolute path is given, we don't try to construct
// a relative path with it.
diff --git a/test/asan/TestCases/suppressions-library.cc b/test/asan/TestCases/suppressions-library.cc
index e95d339168ed..39ede0840105 100644
--- a/test/asan/TestCases/suppressions-library.cc
+++ b/test/asan/TestCases/suppressions-library.cc
@@ -7,7 +7,7 @@
// FIXME: Remove usage of backticks around basename below.
// REQUIRES: shell
-// RUN: echo "interceptor_via_lib:"`basename %dynamiclib` > %t.supp
+// RUN: echo "interceptor_via_lib:"%xdynamiclib_filename > %t.supp
// RUN: %env_asan_opts=suppressions='"%t.supp"' %run %t 2>&1 | FileCheck --check-prefix=CHECK-IGNORE %s
// XFAIL: android
diff --git a/test/asan/TestCases/throw_invoke_test.cc b/test/asan/TestCases/throw_invoke_test.cc
index e6e91d1879cb..bbfa1c7b95ca 100644
--- a/test/asan/TestCases/throw_invoke_test.cc
+++ b/test/asan/TestCases/throw_invoke_test.cc
@@ -1,5 +1,5 @@
// RUN: %clangxx_asan %s -o %t && %run %t
-// RUN: %clangxx_asan %s -o %t -stdlib=libstdc++ -static-libstdc++ && %run %t
+// RUN: %clangxx_asan %s -o %t %linux_static_libstdcplusplus && %run %t
#include <stdio.h>
static volatile int zero = 0;
diff --git a/test/asan/TestCases/verbose-log-path_test.cc b/test/asan/TestCases/verbose-log-path_test.cc
index 3c3db0883f61..8088ff924761 100644
--- a/test/asan/TestCases/verbose-log-path_test.cc
+++ b/test/asan/TestCases/verbose-log-path_test.cc
@@ -1,12 +1,13 @@
-// RUN: %clangxx_asan %s -o %T/verbose-log-path_test-binary
+// RUN: rm -rf %t-dir && mkdir -p %t-dir
+// RUN: %clangxx_asan %s -o %t-dir/verbose-log-path_test-binary
// The glob below requires bash.
// REQUIRES: shell
// Good log_path.
-// RUN: rm -f %T/asan.log.*
-// RUN: %env_asan_opts=log_path=%T/asan.log:log_exe_name=1 not %run %T/verbose-log-path_test-binary 2> %t.out
-// RUN: FileCheck %s --check-prefix=CHECK-ERROR < %T/asan.log.verbose-log-path_test-binary.*
+// RUN: rm -f %t-dir/asan.log.*
+// RUN: %env_asan_opts=log_path=%t-dir/asan.log:log_exe_name=1 not %run %t-dir/verbose-log-path_test-binary 2> %t.out
+// RUN: FileCheck %s --check-prefix=CHECK-ERROR < %t-dir/asan.log.verbose-log-path_test-binary.*
// FIXME: only FreeBSD, NetBSD and Linux have verbose log paths now.
// XFAIL: win32,android
diff --git a/test/asan/lit.cfg b/test/asan/lit.cfg
index 4a08a7b475a2..f8994d069ad8 100644
--- a/test/asan/lit.cfg
+++ b/test/asan/lit.cfg
@@ -48,8 +48,7 @@ config.substitutions.append(('%env_asan_opts=',
# Setup source root.
config.test_source_root = os.path.dirname(__file__)
-# There is no libdl on FreeBSD.
-if config.host_os != 'FreeBSD':
+if config.host_os not in ['FreeBSD', 'NetBSD']:
libdl_flag = "-ldl"
else:
libdl_flag = ""
@@ -102,7 +101,7 @@ config.substitutions.append( ("%clang ", build_invocation(target_cflags)) )
config.substitutions.append( ("%clangxx ", build_invocation(target_cxxflags)) )
config.substitutions.append( ("%clang_asan ", build_invocation(clang_asan_cflags)) )
config.substitutions.append( ("%clangxx_asan ", build_invocation(clang_asan_cxxflags)) )
-config.substitutions.append( ("%shared_libasan", "libclang_rt.asan-%s.so" % config.target_arch))
+config.substitutions.append( ("%shared_libasan", "libclang_rt.asan%s.so" % config.target_suffix))
if config.asan_dynamic:
config.substitutions.append( ("%clang_asan_static ", build_invocation(clang_asan_static_cflags)) )
config.substitutions.append( ("%clangxx_asan_static ", build_invocation(clang_asan_static_cxxflags)) )
@@ -125,7 +124,7 @@ if platform.system() == 'Windows':
clang_cl_asan_invocation = clang_cl_asan_invocation.replace("clang.exe","clang-cl.exe")
config.substitutions.append( ("%clang_cl_asan ", clang_cl_asan_invocation) )
- base_lib = os.path.join(config.compiler_rt_libdir, "clang_rt.asan%%s-%s.lib" % config.target_arch)
+ base_lib = os.path.join(config.compiler_rt_libdir, "clang_rt.asan%%s%s.lib" % config.target_suffix)
config.substitutions.append( ("%asan_lib", base_lib % "") )
config.substitutions.append( ("%asan_cxx_lib", base_lib % "_cxx") )
config.substitutions.append( ("%asan_dll_thunk", base_lib % "_dll_thunk") )
@@ -169,7 +168,7 @@ config.substitutions.append( ("%libdl", libdl_flag) )
config.available_features.add("asan-" + config.bits + "-bits")
# Fast unwinder doesn't work with Thumb
-if re.search('mthumb', config.target_cflags) is not None:
+if re.search('mthumb', config.target_cflags) is None:
config.available_features.add('fast-unwinder-works')
# Turn on leak detection on 64-bit Linux.
@@ -209,8 +208,11 @@ else:
config.substitutions.append(('%pie', '-pie'))
# Only run the tests on supported OSs.
-if config.host_os not in ['Linux', 'Darwin', 'FreeBSD', 'Windows']:
+if config.host_os not in ['Linux', 'Darwin', 'FreeBSD', 'SunOS', 'Windows', 'NetBSD']:
config.unsupported = True
-if config.host_os == 'Darwin' and config.target_arch in ["x86_64", "x86_64h"]:
- config.parallelism_group = "darwin-64bit-sanitizer"
+if config.host_os == 'Darwin':
+ if config.target_arch in ["x86_64", "x86_64h"]:
+ config.parallelism_group = "darwin-64bit-sanitizer"
+ elif config.apple_platform != "osx" and not config.apple_platform.endswith("sim"):
+ config.parallelism_group = "darwin-ios-device-sanitizer"
diff --git a/test/asan/lit.site.cfg.in b/test/asan/lit.site.cfg.in
index 6c8f882bcc2c..6282fd881e5d 100644
--- a/test/asan/lit.site.cfg.in
+++ b/test/asan/lit.site.cfg.in
@@ -5,8 +5,7 @@ config.name_suffix = "@ASAN_TEST_CONFIG_SUFFIX@"
config.target_cflags = "@ASAN_TEST_TARGET_CFLAGS@"
config.clang = "@ASAN_TEST_TARGET_CC@"
config.bits = "@ASAN_TEST_BITS@"
-config.ios = @ASAN_TEST_IOS_PYBOOL@
-config.iossim = @ASAN_TEST_IOSSIM_PYBOOL@
+config.apple_platform = "@ASAN_TEST_APPLE_PLATFORM@"
config.asan_dynamic = @ASAN_TEST_DYNAMIC@
config.target_arch = "@ASAN_TEST_TARGET_ARCH@"
diff --git a/test/builtins/CMakeLists.txt b/test/builtins/CMakeLists.txt
index cabf767223cc..a9199ebf10df 100644
--- a/test/builtins/CMakeLists.txt
+++ b/test/builtins/CMakeLists.txt
@@ -26,6 +26,11 @@ foreach(arch ${BUILTIN_SUPPORTED_ARCH})
string(REPLACE ";" " " BUILTINS_TEST_TARGET_CFLAGS "${BUILTINS_TEST_TARGET_CFLAGS}")
endif()
+ if (${arch} STREQUAL "riscv32")
+ list(APPEND BUILTINS_TEST_TARGET_CFLAGS -fforce-enable-int128)
+ string(REPLACE ";" " " BUILTINS_TEST_TARGET_CFLAGS "${BUILTINS_TEST_TARGET_CFLAGS}")
+ endif()
+
string(TOUPPER ${arch} ARCH_UPPER_CASE)
set(CONFIG_NAME ${ARCH_UPPER_CASE}${OS_NAME}Config)
configure_lit_site_cfg(
diff --git a/test/builtins/TestCases/Darwin/os_version_check_test.c b/test/builtins/TestCases/Darwin/os_version_check_test.c
index 2692cd37edce..bae1f3255065 100644
--- a/test/builtins/TestCases/Darwin/os_version_check_test.c
+++ b/test/builtins/TestCases/Darwin/os_version_check_test.c
@@ -1,4 +1,4 @@
-// RUN: %clang %s -o %t -mmacosx-version-min=10.5 -framework CoreFoundation -DMAJOR=%macos_version_major -DMINOR=%macos_version_minor -DSUBMINOR=%macos_version_subminor
+// RUN: %clang %s -o %t -mmacosx-version-min=10.6 -framework CoreFoundation -DMAJOR=%macos_version_major -DMINOR=%macos_version_minor -DSUBMINOR=%macos_version_subminor
// RUN: %run %t
int __isOSVersionAtLeast(int Major, int Minor, int Subminor);
diff --git a/test/builtins/TestCases/Darwin/os_version_check_test_no_core_foundation.c b/test/builtins/TestCases/Darwin/os_version_check_test_no_core_foundation.c
index 4e0da35cd12d..90c798f6c55f 100644
--- a/test/builtins/TestCases/Darwin/os_version_check_test_no_core_foundation.c
+++ b/test/builtins/TestCases/Darwin/os_version_check_test_no_core_foundation.c
@@ -1,4 +1,4 @@
-// RUN: %clang %s -o %t -mmacosx-version-min=10.5
+// RUN: %clang %s -o %t -mmacosx-version-min=10.6
// RUN: %run %t
int __isOSVersionAtLeast(int Major, int Minor, int Subminor);
diff --git a/test/builtins/Unit/lit.cfg b/test/builtins/Unit/lit.cfg
index 0e17e479e6b6..4b63948b5ef6 100644
--- a/test/builtins/Unit/lit.cfg
+++ b/test/builtins/Unit/lit.cfg
@@ -26,12 +26,12 @@ config.test_source_root = os.path.dirname(__file__)
# Path to the static library
is_msvc = get_required_attr(config, "builtins_is_msvc")
if is_msvc:
- base_lib = os.path.join(config.compiler_rt_libdir, "clang_rt.builtins-%s.lib "
- % config.target_arch)
+ base_lib = os.path.join(config.compiler_rt_libdir, "clang_rt.builtins%s.lib "
+ % config.target_suffix)
config.substitutions.append( ("%librt ", base_lib) )
else:
- base_lib = os.path.join(config.compiler_rt_libdir, "libclang_rt.builtins-%s.a"
- % config.target_arch)
+ base_lib = os.path.join(config.compiler_rt_libdir, "libclang_rt.builtins%s.a"
+ % config.target_suffix)
config.substitutions.append( ("%librt ", base_lib + ' -lc -lm ') )
builtins_source_dir = os.path.join(
diff --git a/test/builtins/Unit/riscv/mulsi3_test.c b/test/builtins/Unit/riscv/mulsi3_test.c
new file mode 100644
index 000000000000..9033004f11dd
--- /dev/null
+++ b/test/builtins/Unit/riscv/mulsi3_test.c
@@ -0,0 +1,119 @@
+// REQUIRES-ANY: riscv32-target-arch
+// RUN: %clang_builtins %s %librt -o %t && %run %t
+//===-- mulsi3_test.c - Test __mulsi3 -------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file tests __mulsi3 for the compiler_rt library.
+//
+//===----------------------------------------------------------------------===//
+
+#include "int_lib.h"
+#include <stdio.h>
+#include <limits.h>
+
+#if !defined(__riscv_mul) && __riscv_xlen == 32
+// Based on mulsi3_test.c
+
+COMPILER_RT_ABI si_int __mulsi3(si_int a, si_int b);
+
+int test__mulsi3(si_int a, si_int b, si_int expected)
+{
+ si_int x = __mulsi3(a, b);
+ if (x != expected)
+ printf("error in __mulsi3: %d * %d = %d, expected %d\n",
+ a, b, __mulsi3(a, b), expected);
+ return x != expected;
+}
+#endif
+
+int main()
+{
+#if !defined(__riscv_mul) && __riscv_xlen == 32
+ if (test__mulsi3(0, 0, 0))
+ return 1;
+ if (test__mulsi3(0, 1, 0))
+ return 1;
+ if (test__mulsi3(1, 0, 0))
+ return 1;
+ if (test__mulsi3(0, 10, 0))
+ return 1;
+ if (test__mulsi3(10, 0, 0))
+ return 1;
+ if (test__mulsi3(0, INT_MAX, 0))
+ return 1;
+ if (test__mulsi3(INT_MAX, 0, 0))
+ return 1;
+
+ if (test__mulsi3(0, -1, 0))
+ return 1;
+ if (test__mulsi3(-1, 0, 0))
+ return 1;
+ if (test__mulsi3(0, -10, 0))
+ return 1;
+ if (test__mulsi3(-10, 0, 0))
+ return 1;
+ if (test__mulsi3(0, INT_MIN, 0))
+ return 1;
+ if (test__mulsi3(INT_MIN, 0, 0))
+ return 1;
+
+ if (test__mulsi3(1, 1, 1))
+ return 1;
+ if (test__mulsi3(1, 10, 10))
+ return 1;
+ if (test__mulsi3(10, 1, 10))
+ return 1;
+ if (test__mulsi3(1, INT_MAX, INT_MAX))
+ return 1;
+ if (test__mulsi3(INT_MAX, 1, INT_MAX))
+ return 1;
+
+ if (test__mulsi3(1, -1, -1))
+ return 1;
+ if (test__mulsi3(1, -10, -10))
+ return 1;
+ if (test__mulsi3(-10, 1, -10))
+ return 1;
+ if (test__mulsi3(1, INT_MIN, INT_MIN))
+ return 1;
+ if (test__mulsi3(INT_MIN, 1, INT_MIN))
+ return 1;
+
+ if (test__mulsi3(46340, 46340, 2147395600))
+ return 1;
+ if (test__mulsi3(-46340, 46340, -2147395600))
+ return 1;
+ if (test__mulsi3(46340, -46340, -2147395600))
+ return 1;
+ if (test__mulsi3(-46340, -46340, 2147395600))
+ return 1;
+
+ if (test__mulsi3(4194303, 8192, 34359730176))
+ return 1;
+ if (test__mulsi3(-4194303, 8192, -34359730176))
+ return 1;
+ if (test__mulsi3(4194303, -8192, -34359730176))
+ return 1;
+ if (test__mulsi3(-4194303, -8192, 34359730176))
+ return 1;
+
+ if (test__mulsi3(8192, 4194303, 34359730176))
+ return 1;
+ if (test__mulsi3(-8192, 4194303, -34359730176))
+ return 1;
+ if (test__mulsi3(8192, -4194303, -34359730176))
+ return 1;
+ if (test__mulsi3(-8192, -4194303, 34359730176))
+ return 1;
+#else
+ printf("skipped\n");
+#endif
+
+ return 0;
+}
diff --git a/test/cfi/CMakeLists.txt b/test/cfi/CMakeLists.txt
index c7fadde53095..4dbbf1759fcc 100644
--- a/test/cfi/CMakeLists.txt
+++ b/test/cfi/CMakeLists.txt
@@ -1,6 +1,6 @@
set(CFI_TESTSUITES)
-macro (add_cfi_test_suites lld thinlto)
+macro (add_cfi_test_suites lld thinlto newpm)
set(suffix)
if (${lld})
set(suffix ${suffix}-lld)
@@ -8,10 +8,14 @@ macro (add_cfi_test_suites lld thinlto)
if (${thinlto})
set(suffix ${suffix}-thinlto)
endif()
+ if (${newpm})
+ set(suffix ${suffix}-newpm)
+ endif()
set(suffix ${suffix}-${CFI_TEST_TARGET_ARCH})
set(CFI_TEST_USE_LLD ${lld})
set(CFI_TEST_USE_THINLTO ${thinlto})
+ set(CFI_TEST_USE_NEWPM ${newpm})
set(CFI_LIT_TEST_MODE Standalone)
set(CFI_TEST_CONFIG_SUFFIX -standalone${suffix})
@@ -40,16 +44,18 @@ foreach(arch ${CFI_TEST_ARCH})
get_test_cc_for_arch(${arch} CFI_TEST_TARGET_CC CFI_TEST_TARGET_CFLAGS)
if (APPLE)
# FIXME: enable ThinLTO tests after fixing http://llvm.org/pr32741
- add_cfi_test_suites(False False)
+ add_cfi_test_suites(False False False)
elseif(WIN32)
- add_cfi_test_suites(True False)
- add_cfi_test_suites(True True)
+ add_cfi_test_suites(True False False)
+ add_cfi_test_suites(True True False)
else()
- add_cfi_test_suites(False False)
- add_cfi_test_suites(False True)
+ add_cfi_test_suites(False False False)
+ add_cfi_test_suites(False True False)
+ add_cfi_test_suites(False False True)
+ add_cfi_test_suites(False True True)
if (COMPILER_RT_HAS_LLD AND NOT arch STREQUAL "i386")
- add_cfi_test_suites(True False)
- add_cfi_test_suites(True True)
+ add_cfi_test_suites(True False False)
+ add_cfi_test_suites(True True False)
endif()
endif()
endforeach()
diff --git a/test/cfi/create-derivers.test b/test/cfi/create-derivers.test
index 8b569d001d89..b651d9be6bd9 100644
--- a/test/cfi/create-derivers.test
+++ b/test/cfi/create-derivers.test
@@ -7,15 +7,15 @@ B0: {{1B|B@@}}: {{.*}} size 1
RUN: %clangxx_cfi -DB32 -flto -c -o %t2.o %S/simple-fail.cpp
RUN: opt -lowertypetests -debug-only=lowertypetests -o /dev/null %t2.o 2>&1 | FileCheck --check-prefix=B32 %s
-B32: {{1B|B@@}}: {{.*}} size 24
+B32: {{1B|B@@}}: {{.*}} size 2{{3|4}}
B32-NOT: all-ones
RUN: %clangxx_cfi -DB64 -flto -c -o %t3.o %S/simple-fail.cpp
RUN: opt -lowertypetests -debug-only=lowertypetests -o /dev/null %t3.o 2>&1 | FileCheck --check-prefix=B64 %s
-B64: {{1B|B@@}}: {{.*}} size 54
+B64: {{1B|B@@}}: {{.*}} size 5{{3|4}}
B64-NOT: all-ones
RUN: %clangxx_cfi -DBM -flto -c -o %t4.o %S/simple-fail.cpp
RUN: opt -lowertypetests -debug-only=lowertypetests -o /dev/null %t4.o 2>&1 | FileCheck --check-prefix=BM %s
-BM: {{1B|B@@}}: {{.*}} size 84
+BM: {{1B|B@@}}: {{.*}} size 8{{3|4}}
BM-NOT: all-ones
diff --git a/test/cfi/cross-dso-diagnostic.cpp b/test/cfi/cross-dso-diagnostic.cpp
new file mode 100644
index 000000000000..f3782dae0272
--- /dev/null
+++ b/test/cfi/cross-dso-diagnostic.cpp
@@ -0,0 +1,47 @@
+// Check that cross-DSO diagnostics print the names of both modules
+
+// RUN: %clangxx_cfi_diag -g -DSHARED_LIB -fPIC -shared -o %dynamiclib %s %ld_flags_rpath_so
+// RUN: %clangxx_cfi_diag -g -o %t_exe_suffix %s %ld_flags_rpath_exe
+// RUN: %t_exe_suffix 2>&1 | FileCheck -DDSONAME=%xdynamiclib_namespec %s
+
+// UNSUPPORTED: win32
+// REQUIRES: cxxabi
+
+#include <dlfcn.h>
+#include <stdio.h>
+
+struct S1 {
+ virtual void f1();
+};
+
+#ifdef SHARED_LIB
+
+void S1::f1() {}
+
+__attribute__((visibility("default"))) extern "C"
+void* dso_symbol() { return new S1(); }
+
+#else
+
+int main() {
+ void* (*fp)(void) =
+ reinterpret_cast<void*(*)(void)>(dlsym(RTLD_DEFAULT, "dso_symbol"));
+ if (!fp) {
+ perror("failed to resolve dso_symbol");
+ return 1;
+ }
+
+ // CHECK: runtime error: control flow integrity check for type 'void *()' failed during indirect function call
+ // CHECK: dso_symbol defined here
+ // CHECK: check failed in {{.*}}_exe_suffix, destination function located in {{.*}}[[DSONAME]]
+ void *S = fp(); // trigger cfi-icall failure
+
+ // CHECK: runtime error: control flow integrity check for type 'S1' failed during cast to unrelated type
+ // CHECK: invalid vtable
+ // CHECK: check failed in {{.*}}_exe_suffix, vtable located in {{.*}}[[DSONAME]]
+ S1 *Scast = reinterpret_cast<S1*>(S); // trigger cfi-unrelated-cast failure
+
+ return 0;
+}
+
+#endif // SHARED_LIB
diff --git a/test/cfi/cross-dso/icall/dlopen.cpp b/test/cfi/cross-dso/icall/dlopen.cpp
index d238a7acec89..c9674c3fb412 100644
--- a/test/cfi/cross-dso/icall/dlopen.cpp
+++ b/test/cfi/cross-dso/icall/dlopen.cpp
@@ -83,10 +83,12 @@ static void save_code(char *p) {
}
static void restore_code() {
- char *code = (char *)mmap(real_start, kCodeSize, PROT_WRITE | PROT_EXEC,
- MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, 0, 0);
+ char *code =
+ (char *)mmap(real_start, kCodeSize, PROT_READ | PROT_WRITE | PROT_EXEC,
+ MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, 0, 0);
assert(code == real_start);
memcpy(code, saved_code, kCodeSize);
+ __builtin___clear_cache(code, code + kCodeSize);
}
int main(int argc, char *argv[]) {
diff --git a/test/cfi/lit.site.cfg.in b/test/cfi/lit.site.cfg.in
index eb9b44137fdf..a735e8812acd 100644
--- a/test/cfi/lit.site.cfg.in
+++ b/test/cfi/lit.site.cfg.in
@@ -7,6 +7,7 @@ config.target_cflags = "@CFI_TEST_TARGET_CFLAGS@"
config.use_lld = @CFI_TEST_USE_LLD@
config.use_lto = True # CFI *requires* LTO.
config.use_thinlto = @CFI_TEST_USE_THINLTO@
+config.use_newpm = @CFI_TEST_USE_NEWPM@
lit_config.load_config(config, "@COMPILER_RT_BINARY_DIR@/test/lit.common.configured")
lit_config.load_config(config, "@CMAKE_CURRENT_SOURCE_DIR@/lit.cfg")
diff --git a/test/cfi/mfcall.cpp b/test/cfi/mfcall.cpp
new file mode 100644
index 000000000000..6e22e3f3d711
--- /dev/null
+++ b/test/cfi/mfcall.cpp
@@ -0,0 +1,96 @@
+// UNSUPPORTED: win32
+
+// RUN: %clangxx_cfi -o %t %s
+// RUN: %expect_crash %run %t a
+// RUN: %expect_crash %run %t b
+// RUN: %expect_crash %run %t c
+// RUN: %expect_crash %run %t d
+// RUN: %expect_crash %run %t e
+// RUN: %run %t f
+// RUN: %run %t g
+
+// RUN: %clangxx_cfi_diag -o %t2 %s
+// RUN: %run %t2 a 2>&1 | FileCheck --check-prefix=A %s
+// RUN: %run %t2 b 2>&1 | FileCheck --check-prefix=B %s
+// RUN: %run %t2 c 2>&1 | FileCheck --check-prefix=C %s
+// RUN: %run %t2 d 2>&1 | FileCheck --check-prefix=D %s
+// RUN: %run %t2 e 2>&1 | FileCheck --check-prefix=E %s
+
+#include <assert.h>
+#include <string.h>
+
+struct SBase1 {
+ void b1() {}
+};
+
+struct SBase2 {
+ void b2() {}
+};
+
+struct S : SBase1, SBase2 {
+ void f1() {}
+ int f2() { return 1; }
+ virtual void g1() {}
+ virtual int g2() { return 1; }
+ virtual int g3() { return 1; }
+};
+
+struct T {
+ void f1() {}
+ int f2() { return 2; }
+ virtual void g1() {}
+ virtual int g2() { return 2; }
+ virtual void g3() {}
+};
+
+typedef void (S::*S_void)();
+
+typedef int (S::*S_int)();
+typedef int (T::*T_int)();
+
+template <typename To, typename From>
+To bitcast(From f) {
+ assert(sizeof(To) == sizeof(From));
+ To t;
+ memcpy(&t, &f, sizeof(f));
+ return t;
+}
+
+int main(int argc, char **argv) {
+ S s;
+ T t;
+
+ switch (argv[1][0]) {
+ case 'a':
+ // A: runtime error: control flow integrity check for type 'int (S::*)()' failed during non-virtual pointer to member function call
+ // A: note: S::f1() defined here
+ (s.*bitcast<S_int>(&S::f1))();
+ break;
+ case 'b':
+ // B: runtime error: control flow integrity check for type 'int (T::*)()' failed during non-virtual pointer to member function call
+ // B: note: S::f2() defined here
+ (t.*bitcast<T_int>(&S::f2))();
+ break;
+ case 'c':
+ // C: runtime error: control flow integrity check for type 'int (S::*)()' failed during virtual pointer to member function call
+ // C: note: vtable is of type 'S'
+ (s.*bitcast<S_int>(&S::g1))();
+ break;
+ case 'd':
+ // D: runtime error: control flow integrity check for type 'int (S::*)()' failed during virtual pointer to member function call
+ // D: note: vtable is of type 'T'
+ (reinterpret_cast<S &>(t).*&S::g2)();
+ break;
+ case 'e':
+ // E: runtime error: control flow integrity check for type 'void (S::*)()' failed during virtual pointer to member function call
+ // E: note: vtable is of type 'S'
+ (s.*bitcast<S_void>(&T::g3))();
+ break;
+ case 'f':
+ (s.*&SBase1::b1)();
+ break;
+ case 'g':
+ (s.*&SBase2::b2)();
+ break;
+ }
+}
diff --git a/test/cfi/simple-pass.cpp b/test/cfi/simple-pass.cpp
index aba09be2d816..de791fc1073f 100644
--- a/test/cfi/simple-pass.cpp
+++ b/test/cfi/simple-pass.cpp
@@ -1,5 +1,10 @@
+// -mretpoline does not work yet on Darwin.
+// XFAIL: darwin
+
// RUN: %clangxx_cfi -o %t %s
// RUN: %run %t
+// RUN: %clangxx_cfi -mretpoline -o %t2 %s
+// RUN: %run %t2
// Tests that the CFI mechanism does not crash the program when making various
// kinds of valid calls involving classes with various different linkages and
diff --git a/test/cfi/target_uninstrumented.cpp b/test/cfi/target_uninstrumented.cpp
index 5df0738c078b..6379b7e12f44 100644
--- a/test/cfi/target_uninstrumented.cpp
+++ b/test/cfi/target_uninstrumented.cpp
@@ -32,12 +32,14 @@ void A::f() {}
int main(int argc, char *argv[]) {
void *p = create_B();
// CHECK: runtime error: control flow integrity check for type 'A' failed during cast to unrelated type
- // CHECK: invalid vtable in module {{.*}}libtarget_uninstrumented.cpp.dynamic.so
+ // CHECK: invalid vtable
+ // CHECK: check failed in {{.*}}, vtable located in {{.*}}libtarget_uninstrumented.cpp.dynamic.so
A *a = (A *)p;
memset(p, 0, sizeof(A));
+
// CHECK: runtime error: control flow integrity check for type 'A' failed during cast to unrelated type
- // CHECK-NOT: invalid vtable in module
// CHECK: invalid vtable
+ // CHECK: check failed in {{.*}}, vtable located in (unknown)
a = (A *)p;
// CHECK: done
fprintf(stderr, "done %p\n", a);
diff --git a/test/dfsan/custom.cc b/test/dfsan/custom.cc
index b36db01bc48c..71422f7ce834 100644
--- a/test/dfsan/custom.cc
+++ b/test/dfsan/custom.cc
@@ -3,8 +3,6 @@
// RUN: %clang_dfsan -DSTRICT_DATA_DEPENDENCIES %s -o %t && %run %t
// RUN: %clang_dfsan -DSTRICT_DATA_DEPENDENCIES -mllvm -dfsan-args-abi %s -o %t && %run %t
-// XFAIL: target-is-mips64,target-is-mips64el
-
// Tests custom implementations of various glibc functions.
#include <sanitizer/dfsan_interface.h>
diff --git a/test/dfsan/trace-cmp.c b/test/dfsan/trace-cmp.c
new file mode 100644
index 000000000000..0645363b2605
--- /dev/null
+++ b/test/dfsan/trace-cmp.c
@@ -0,0 +1,50 @@
+// Checks that dfsan works with trace-cmp instrumentation, even if some hooks
+// are not defined (relies on week hooks implemented in dfsan).
+//
+// RUN: %clang_dfsan -fsanitize-coverage=trace-pc-guard,pc-table,func,trace-cmp %s -o %t
+// RUN: %run %t 2>&1 | FileCheck %s
+
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+
+#include <sanitizer/dfsan_interface.h>
+
+uint32_t a4, b4;
+uint64_t a8, b8;
+
+// Define just two hooks, and leave others undefined.
+void __dfsw___sanitizer_cov_trace_const_cmp4(uint8_t a, uint8_t b,
+ dfsan_label l1, dfsan_label l2) {
+ printf("const_cmp4 %d %d\n", a, b);
+}
+void __dfsw___sanitizer_cov_trace_cmp8(uint8_t a, uint8_t b, dfsan_label l1,
+ dfsan_label l2) {
+ printf("cmp8 %d %d\n", a, b);
+}
+
+int main(int argc, char **argv) {
+ printf("MAIN\n");
+ // CHECK: MAIN
+
+ if (a4 != b4) abort();
+ if (a4 == 42) abort();
+ // CHECK: const_cmp4 42 0
+ if (a8 != b8) abort();
+ // CHECK: cmp8 0 0
+ if (a8 == 66) abort();
+
+ switch (10 / (a4 + 2)) {
+ case 1: abort();
+ case 2: exit(1);
+ case 5:
+ printf("SWITCH OK\n");
+ break;
+ }
+ // CHECK: SWITCH OK
+
+
+ printf("DONE\n");
+ // CHECK: DONE
+ return 0;
+}
diff --git a/test/fuzzer/AbsNegAndConstant64Test.cpp b/test/fuzzer/AbsNegAndConstant64Test.cpp
index abeb784e9a11..0ba80b61d033 100644
--- a/test/fuzzer/AbsNegAndConstant64Test.cpp
+++ b/test/fuzzer/AbsNegAndConstant64Test.cpp
@@ -14,7 +14,8 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
uint64_t y;
memcpy(&x, Data, sizeof(x));
memcpy(&y, Data + sizeof(x), sizeof(y));
- if (llabs(x) < 0 && y == 0xbaddcafedeadbeefULL) {
+ volatile int64_t abs_x = llabs(x);
+ if (abs_x < 0 && y == 0xbaddcafedeadbeefULL) {
printf("BINGO; Found the target, exiting; x = 0x%lx y 0x%lx\n", x, y);
fflush(stdout);
exit(1);
diff --git a/test/fuzzer/AbsNegAndConstantTest.cpp b/test/fuzzer/AbsNegAndConstantTest.cpp
index 049db0a60c3d..a3f534980010 100644
--- a/test/fuzzer/AbsNegAndConstantTest.cpp
+++ b/test/fuzzer/AbsNegAndConstantTest.cpp
@@ -14,7 +14,8 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
unsigned y;
memcpy(&x, Data, sizeof(x));
memcpy(&y, Data + sizeof(x), sizeof(y));
- if (abs(x) < 0 && y == 0xbaddcafe) {
+ volatile int abs_x = abs(x);
+ if (abs_x < 0 && y == 0xbaddcafe) {
printf("BINGO; Found the target, exiting; x = 0x%x y 0x%x\n", x, y);
fflush(stdout);
exit(1);
diff --git a/test/fuzzer/AcquireCrashStateTest.cpp b/test/fuzzer/AcquireCrashStateTest.cpp
new file mode 100644
index 000000000000..0fe71fd46bf4
--- /dev/null
+++ b/test/fuzzer/AcquireCrashStateTest.cpp
@@ -0,0 +1,18 @@
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+
+// Ensures that error reports are suppressed after
+// __sanitizer_acquire_crash_state() has been called the first time.
+#include "sanitizer/common_interface_defs.h"
+
+#include <cassert>
+#include <cstdint>
+#include <cstdlib>
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
+ assert(Data);
+ if (Size == 0) return 0;
+ __sanitizer_acquire_crash_state();
+ exit(0); // No report should be generated here.
+}
+
diff --git a/test/fuzzer/Bingo.h b/test/fuzzer/Bingo.h
new file mode 100644
index 000000000000..09fc61e2a0cb
--- /dev/null
+++ b/test/fuzzer/Bingo.h
@@ -0,0 +1 @@
+#define BINGO aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
diff --git a/test/fuzzer/CMakeLists.txt b/test/fuzzer/CMakeLists.txt
index bd511123255b..ef46ec4a9061 100644
--- a/test/fuzzer/CMakeLists.txt
+++ b/test/fuzzer/CMakeLists.txt
@@ -1,43 +1,109 @@
set(LIBFUZZER_TEST_DEPS ${SANITIZER_COMMON_LIT_TEST_DEPS})
-list(REMOVE_ITEM LIBFUZZER_TEST_DEPS SanitizerLintCheck)
if (NOT COMPILER_RT_STANDALONE_BUILD)
list(APPEND LIBFUZZER_TEST_DEPS fuzzer asan ubsan)
+ if (COMPILER_RT_HAS_MSAN)
+ list(APPEND LIBFUZZER_TEST_DEPS msan)
+ endif()
+ if (COMPILER_RT_HAS_DFSAN)
+ list(APPEND LIBFUZZER_TEST_DEPS dfsan)
+ endif()
+ if(NOT APPLE AND COMPILER_RT_HAS_LLD)
+ list(APPEND LIBFUZZER_TEST_DEPS lld)
+ endif()
+endif()
+
+if (APPLE)
+ darwin_filter_host_archs(FUZZER_SUPPORTED_ARCH FUZZER_SUPPORTED_ARCH)
endif()
if(COMPILER_RT_INCLUDE_TESTS)
list(APPEND LIBFUZZER_TEST_DEPS FuzzerUnitTests)
endif()
-set(LIBFUZZER_TESTSUITES)
-
+add_custom_target(check-fuzzer)
if(COMPILER_RT_INCLUDE_TESTS)
# libFuzzer unit tests.
configure_lit_site_cfg(
${CMAKE_CURRENT_SOURCE_DIR}/unit/lit.site.cfg.in
${CMAKE_CURRENT_BINARY_DIR}/unit/lit.site.cfg)
- list(APPEND LIBFUZZER_TESTSUITES ${CMAKE_CURRENT_BINARY_DIR}/unit)
+ add_lit_testsuite(check-fuzzer-unit "Running Fuzzer unit tests"
+ ${CMAKE_CURRENT_BINARY_DIR}/unit
+ DEPENDS ${LIBFUZZER_TEST_DEPS})
+ set_target_properties(check-fuzzer-unit PROPERTIES FOLDER "Compiler-RT Tests")
+ add_dependencies(check-fuzzer check-fuzzer-unit)
endif()
-foreach(arch ${FUZZER_SUPPORTED_ARCH})
- set(LIBFUZZER_TEST_COMPILER ${COMPILER_RT_TEST_COMPILER})
- get_test_cc_for_arch(${arch} LIBFUZZER_TEST_COMPILER LIBFUZZER_TEST_FLAGS)
+macro(test_fuzzer stdlib)
+ cmake_parse_arguments(TEST "" "" "DEPS" ${ARGN})
+ string(REPLACE "+" "x" stdlib_name ${stdlib})
+ string(REPLACE "-" ";" stdlib_list ${stdlib_name})
+ set(STDLIB_CAPITALIZED "")
+ foreach(part IN LISTS stdlib_list)
+ string(SUBSTRING ${part} 0 1 first_letter)
+ string(TOUPPER ${first_letter} first_letter)
+ string(REGEX REPLACE "^.(.*)" "${first_letter}\\1" part "${part}")
+ set(STDLIB_CAPITALIZED "${STDLIB_CAPITALIZED}${part}")
+ endforeach()
+ foreach(arch ${FUZZER_SUPPORTED_ARCH})
+ set(LIBFUZZER_TEST_COMPILER ${COMPILER_RT_TEST_COMPILER})
+ get_test_cc_for_arch(${arch} LIBFUZZER_TEST_COMPILER LIBFUZZER_TEST_FLAGS)
- string(TOUPPER ${arch} ARCH_UPPER_CASE)
- set(CONFIG_NAME ${ARCH_UPPER_CASE}${OS_NAME}Config)
+ set(LIBFUZZER_TEST_APPLE_PLATFORM "osx")
- # LIT-based libFuzzer tests.
- configure_lit_site_cfg(
- ${CMAKE_CURRENT_SOURCE_DIR}/lit.site.cfg.in
- ${CMAKE_CURRENT_BINARY_DIR}/${CONFIG_NAME}/lit.site.cfg
- )
- list(APPEND LIBFUZZER_TESTSUITES ${CMAKE_CURRENT_BINARY_DIR}/${CONFIG_NAME})
+ set(LIBFUZZER_TEST_STDLIB ${stdlib})
+
+ string(TOUPPER ${arch} ARCH_UPPER_CASE)
+ set(CONFIG_NAME ${ARCH_UPPER_CASE}${STDLIB_CAPITALIZED}${OS_NAME}Config)
-endforeach()
+ # LIT-based libFuzzer tests.
+ configure_lit_site_cfg(
+ ${CMAKE_CURRENT_SOURCE_DIR}/lit.site.cfg.in
+ ${CMAKE_CURRENT_BINARY_DIR}/${CONFIG_NAME}/lit.site.cfg
+ )
-set(EXCLUDE_FROM_ALL ON)
+ add_lit_testsuite(check-fuzzer-${stdlib_name}-${arch}
+ "Running libFuzzer ${stdlib} tests for arch ${arch}"
+ ${CMAKE_CURRENT_BINARY_DIR}/${CONFIG_NAME}/
+ DEPENDS ${LIBFUZZER_TEST_DEPS})
+ if(TEST_DEPS)
+ add_dependencies(check-fuzzer-${stdlib_name}-${arch} ${TEST_DEPS})
+ endif()
+ set_target_properties(check-fuzzer-${stdlib_name}-${arch}
+ PROPERTIES FOLDER "Compiler-RT Tests")
+ add_dependencies(check-fuzzer check-fuzzer-${stdlib_name}-${arch})
+ endforeach()
+endmacro()
-add_lit_testsuite(check-fuzzer "Running Fuzzer tests"
- ${LIBFUZZER_TESTSUITES}
- DEPENDS ${LIBFUZZER_TEST_DEPS})
-set_target_properties(check-fuzzer PROPERTIES FOLDER "Compiler-RT Tests")
+test_fuzzer("default")
+if("${CMAKE_SYSTEM_NAME}" STREQUAL "Linux")
+ if(TARGET cxx_shared)
+ test_fuzzer("libc++" DEPS cxx_shared)
+ endif()
+ if(TARGET cxx_static)
+ test_fuzzer("static-libc++" DEPS cxx_static)
+ endif()
+endif()
+
+if (APPLE)
+ set(EXCLUDE_FROM_ALL ON)
+
+ foreach(arch ${DARWIN_ios_ARCHS})
+ set(LIBFUZZER_TEST_APPLE_PLATFORM "ios")
+ set(LIBFUZZER_TEST_TARGET_ARCH ${arch})
+ set(LIBFUZZER_TEST_FLAGS "-arch ${arch} -isysroot ${DARWIN_ios_SYSROOT} ${COMPILER_RT_TEST_COMPILER_CFLAGS}")
+ set(LIBFUZZER_TEST_CONFIG_SUFFIX "-${arch}-${LIBFUZZER_TEST_APPLE_PLATFORM}")
+ string(TOUPPER ${arch} ARCH_UPPER_CASE)
+ set(CONFIG_NAME "IOS${ARCH_UPPER_CASE}Config")
+ configure_lit_site_cfg(
+ ${CMAKE_CURRENT_SOURCE_DIR}/lit.site.cfg.in
+ ${CMAKE_CURRENT_BINARY_DIR}/${CONFIG_NAME}/lit.site.cfg
+ )
+ add_lit_testsuite(check-fuzzer-ios-${arch} "libFuzzer iOS ${arch} tests"
+ ${CMAKE_CURRENT_BINARY_DIR}/${CONFIG_NAME}/
+ DEPENDS ${LIBFUZZER_TEST_DEPS})
+
+ endforeach()
+
+ set(EXCLUDE_FROM_ALL OFF)
+endif()
diff --git a/test/fuzzer/CleanseTest.cpp b/test/fuzzer/CleanseTest.cpp
index ee1845701269..d4efa12bb207 100644
--- a/test/fuzzer/CleanseTest.cpp
+++ b/test/fuzzer/CleanseTest.cpp
@@ -1,7 +1,7 @@
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
-// Test the the fuzzer is able to 'cleanse' the reproducer
+// Test the fuzzer is able to 'cleanse' the reproducer
// by replacing all irrelevant bytes with garbage.
#include <cstddef>
#include <cstdint>
diff --git a/test/fuzzer/ExplodeDFSanLabelsTest.cpp b/test/fuzzer/ExplodeDFSanLabelsTest.cpp
new file mode 100644
index 000000000000..0decff8ff086
--- /dev/null
+++ b/test/fuzzer/ExplodeDFSanLabelsTest.cpp
@@ -0,0 +1,23 @@
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+
+// When tracing data flow, explode the number of DFSan labels.
+#include <cstddef>
+#include <cstdint>
+
+static volatile int sink;
+
+__attribute__((noinline))
+void f(uint8_t a, uint8_t b, uint8_t c, uint8_t d) {
+ if (a == b + 1 && c == d + 2)
+ sink++;
+}
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
+ for (size_t a = 0; a < Size; a++)
+ for (size_t b = 0; b < Size; b++)
+ for (size_t c = 0; c < Size; c++)
+ for (size_t d = 0; d < Size; d++)
+ f(Data[a], Data[b], Data[c], Data[d]);
+ return 0;
+}
diff --git a/test/fuzzer/LeakTest.cpp b/test/fuzzer/LeakTest.cpp
index ea89e3901057..f259e9d359f4 100644
--- a/test/fuzzer/LeakTest.cpp
+++ b/test/fuzzer/LeakTest.cpp
@@ -5,7 +5,7 @@
#include <cstddef>
#include <cstdint>
-static volatile void *Sink;
+static void * volatile Sink;
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
if (Size > 0 && *Data == 'H') {
diff --git a/test/fuzzer/MultipleConstraintsOnSmallInputTest.cpp b/test/fuzzer/MultipleConstraintsOnSmallInputTest.cpp
new file mode 100644
index 000000000000..8e24acbcf2d9
--- /dev/null
+++ b/test/fuzzer/MultipleConstraintsOnSmallInputTest.cpp
@@ -0,0 +1,4129 @@
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+// echo -en 'Im_so_cute&pretty_:)' > crash
+//
+#include <stddef.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+// Force noinline, as this test might be interesting for experimenting with
+// data flow tracing approach started in https://reviews.llvm.org/D46666.
+__attribute__((noinline))
+int func1(uint8_t a1, uint8_t a2) {
+ char v = (a1 ^ a2);
+ if ( v <= 15 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func2(uint8_t a1, uint8_t a2) {
+ char v = (a1 & a2);
+ if ( v > 80 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func3(uint8_t a1, uint8_t a2) {
+ char v = (a1 & a2);
+ if ( v > 48 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func4(uint8_t a1, uint8_t a2, uint8_t a3) {
+ char v = ((a1 & a2)) ^ a3;
+ if ( v > 44 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func5(uint8_t a1, uint8_t a2) {
+ char v = (a1 & a2);
+ if ( v <= 72 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func6(uint8_t a1, uint8_t a2) {
+ char v = (a1 & a2);
+ if ( v <= 72 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func7(uint8_t a1, uint8_t a2) {
+ char v = (a1 ^ a2);
+ if ( v <= 43 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func8(uint8_t a1, uint8_t a2) {
+ char v = (a1 ^ a2);
+ if ( v <= 66 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func9(uint8_t a1, uint8_t a2) {
+ char v = (a1 ^ a2);
+ if ( v > 16 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func10(uint8_t a1, uint8_t a2) {
+ char v = (a1 ^ a2);
+ if ( v > 83 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func11(uint8_t a1, uint8_t a2) {
+ char v = (a1 ^ a2);
+ if ( v <= 117 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func12(uint8_t a1, uint8_t a2) {
+ char v = a1 | a2;
+ if ( v <= 16 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func13(uint8_t a1, uint8_t a2) {
+ char v = (a1 & a2);
+ if ( v <= 80 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func14(uint8_t a1) {
+ char v = ~a1;
+ if ( v > 1 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func15(uint8_t a1, uint8_t a2) {
+ char v = a1 | a2;
+ if ( v <= 116 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func16(uint8_t a1) {
+ char v = a1 >> 5;
+ if ( v <= 0 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func17(uint8_t a1) {
+ char v = ~a1;
+ if ( v > 1 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func18(uint8_t a1, uint8_t a2) {
+ char v = (a1 ^ a2);
+ if ( v <= 28 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func19(uint8_t a1, uint8_t a2) {
+ char v = (a1 ^ a2);
+ if ( v > 18 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func20(uint8_t a1, uint8_t a2) {
+ char v = (a1 & a2);
+ if ( v <= 47 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func21(uint8_t a1, uint8_t a2, uint8_t a3) {
+ char v = (((a1 ^ a2))) & a3;
+ if ( v > 108 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func22(uint8_t a1) {
+ char v = ~a1;
+ if ( v > 1 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func23(uint8_t a1, uint8_t a2) {
+ char v = (a1 ^ a2);
+ if ( v <= 7 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func24(uint8_t a1) {
+ char v = (char)a1 >> 1;
+ if ( v <= 25 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func25(uint8_t a1) {
+ char v = ~a1;
+ if ( v > 1 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func26(uint8_t a1, uint8_t a2) {
+ char v = (a1 & a2);
+ if ( v <= 41 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func27(uint8_t a1) {
+ char v = (char)a1 >> 1;
+ if ( v <= 14 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func28(uint8_t a1) {
+ char v = ~a1;
+ if ( v > 1 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func29(uint8_t a1) {
+ char v = a1 >> 5;
+ if ( v > 48 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func30(uint8_t a1) {
+ char v = ~a1;
+ if ( v > 1 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func31(uint8_t a1, uint8_t a2) {
+ char v = (a1 ^ a2);
+ if ( v > 45 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func32(uint8_t a1, uint8_t a2) {
+ char v = (a1 & a2);
+ if ( v <= 0 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func33(uint8_t a1) {
+ char v = ~a1;
+ if ( v > 1 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func34(uint8_t a1, uint8_t a2) {
+ char v = (a1 ^ a2);
+ if ( v <= 95 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func35(uint8_t a1) {
+ char v = a1 >> 5;
+ if ( v > 12 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func36(uint8_t a1, uint8_t a2) {
+ char v = a1 | a2;
+ if ( v <= 121 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func37(uint8_t a1) {
+ char v = ~a1;
+ if ( v > 1 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func38(uint8_t a1, uint8_t a2) {
+ char v = (a1 & a2);
+ if ( v <= 61 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func39(uint8_t a1, uint8_t a2) {
+ char v = (a1 ^ a2);
+ if ( v > 94 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func40(uint8_t a1, uint8_t a2) {
+ char v = (a1 ^ a2);
+ if ( v > 125 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func41(uint8_t a1, uint8_t a2) {
+ char v = (a1 & a2);
+ if ( v <= 0 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func42(uint8_t a1, uint8_t a2, uint8_t a3) {
+ char v = (((a1 ^ a2))) & a3;
+ if ( v > 66 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func43(uint8_t a1) {
+ char v = ~a1;
+ if ( v > 1 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func44(uint8_t a1) {
+ char v = a1 >> 5;
+ if ( v <= 0 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func45(uint8_t a1) {
+ char v = ~a1;
+ if ( v > 1 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func46(uint8_t a1, uint8_t a2) {
+ char v = (a1 ^ a2);
+ if ( v > 106 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func47(uint8_t a1, uint8_t a2) {
+ char v = (a1 & a2);
+ if ( v <= 33 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func48(uint8_t a1, uint8_t a2) {
+ char v = a1 | a2;
+ if ( v <= 118 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func49(uint8_t a1, uint8_t a2) {
+ char v = (a1 & a2);
+ if ( v > 58 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func50(uint8_t a1, uint8_t a2) {
+ char v = (a1 ^ a2);
+ if ( v <= 42 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func51(uint8_t a1, uint8_t a2) {
+ char v = (a1 ^ a2);
+ if ( v <= 46 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func52(uint8_t a1, uint8_t a2) {
+ char v = (a1 & a2);
+ if ( v <= 94 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func53(uint8_t a1, uint8_t a2) {
+ char v = (a1 ^ a2);
+ if ( v <= 66 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func54(uint8_t a1, uint8_t a2) {
+ char v = (a1 ^ a2);
+ if ( v <= 23 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func55(uint8_t a1, uint8_t a2) {
+ char v = (a1 & a2);
+ if ( v <= 17 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func56(uint8_t a1, uint8_t a2) {
+ char v = (a1 & a2);
+ if ( v > 90 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func57(uint8_t a1, uint8_t a2) {
+ char v = (a1 ^ a2);
+ if ( v > 63 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func58(uint8_t a1, uint8_t a2) {
+ char v = (a1 & a2);
+ if ( v > 102 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func59(uint8_t a1, uint8_t a2) {
+ char v = (a1 & a2);
+ if ( v <= 49 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func60(uint8_t a1, uint8_t a2) {
+ char v = (a1 ^ a2);
+ if ( v > 26 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func61(uint8_t a1, uint8_t a2) {
+ char v = (a1 ^ a2);
+ if ( v > 55 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func62(uint8_t a1, uint8_t a2) {
+ char v = (a1 & a2);
+ if ( v > 103 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func63(uint8_t a1, uint8_t a2) {
+ char v = (a1 & a2);
+ if ( v <= 0 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func64(uint8_t a1, uint8_t a2) {
+ char v = (a1 ^ a2);
+ if ( v <= 34 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func65(uint8_t a1, uint8_t a2) {
+ char v = (a1 & a2);
+ if ( v > 90 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func66(uint8_t a1, uint8_t a2) {
+ char v = (a1 ^ a2);
+ if ( v > 4 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func67(uint8_t a1, uint8_t a2) {
+ char v = (a1 ^ a2);
+ if ( v > 50 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func68(uint8_t a1, uint8_t a2) {
+ char v = (a1 & a2);
+ if ( v <= 37 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func69(uint8_t a1, uint8_t a2) {
+ char v = (a1 ^ a2);
+ if ( v > 48 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func70(uint8_t a1) {
+ char v = a1 << 6;
+ if ( v > 1 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func71(uint8_t a1, uint8_t a2) {
+ char v = a1 | a2;
+ if ( v <= 85 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func72(uint8_t a1, uint8_t a2) {
+ char v = (a1 ^ a2);
+ if ( v <= 66 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func73(uint8_t a1, uint8_t a2) {
+ char v = (a1 & a2);
+ if ( v <= 30 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func74(uint8_t a1, uint8_t a2) {
+ char v = (a1 ^ a2);
+ if ( v > 118 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func75(uint8_t a1, uint8_t a2, uint8_t a3) {
+ char v = ((a1 & a2)) | a3;
+ if ( v <= 59 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func76(uint8_t a1, uint8_t a2) {
+ char v = (a1 ^ a2);
+ if ( v <= 94 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func77(uint8_t a1, uint8_t a2) {
+ char v = (a1 & a2);
+ if ( v <= 30 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func78(uint8_t a1, uint8_t a2) {
+ char v = (a1 ^ a2);
+ if ( v > 32 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func79(uint8_t a1) {
+ char v = 16 * a1;
+ if ( v > 1 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func80(uint8_t a1, uint8_t a2, uint8_t a3) {
+ char v = ((a1 ^ a2)) | a3;
+ if ( v <= 94 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func81(uint8_t a1, uint8_t a2) {
+ char v = a1 | a2;
+ if ( v > 120 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func82(uint8_t a1, uint8_t a2) {
+ char v = (a1 & a2);
+ if ( v > 81 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func83(uint8_t a1, uint8_t a2) {
+ char v = a1 | a2;
+ if ( v > 119 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func84(uint8_t a1, uint8_t a2) {
+ char v = (a1 ^ a2);
+ if ( v <= 16 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func85(uint8_t a1) {
+ char v = 2 * a1;
+ if ( v > 1 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func86(uint8_t a1, uint8_t a2) {
+ char v = a1 | a2;
+ if ( v <= 66 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func87(uint8_t a1, uint8_t a2) {
+ char v = (a1 & a2);
+ if ( v <= 84 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func88(uint8_t a1, uint8_t a2) {
+ char v = (a1 & a2);
+ if ( v > 118 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func89(uint8_t a1, uint8_t a2) {
+ char v = (a1 ^ a2);
+ if ( v > 47 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func90(uint8_t a1, uint8_t a2) {
+ char v = a1 | a2;
+ if ( v <= 60 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func91(uint8_t a1, uint8_t a2) {
+ char v = (a1 & a2);
+ if ( v <= 13 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func92(uint8_t a1, uint8_t a2) {
+ char v = (a1 ^ a2);
+ if ( v <= 38 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func93(uint8_t a1, uint8_t a2) {
+ char v = (a1 ^ a2);
+ if ( v > 67 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func94(uint8_t a1) {
+ char v = 16 * a1;
+ if ( v > 1 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func95(uint8_t a1, uint8_t a2) {
+ char v = a1 | a2;
+ if ( v <= 94 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func96(uint8_t a1, uint8_t a2) {
+ char v = (a1 & a2);
+ if ( v > 67 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func97(uint8_t a1, uint8_t a2) {
+ char v = (a1 & a2);
+ if ( v > 48 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func98(uint8_t a1, uint8_t a2) {
+ char v = (a1 ^ a2);
+ if ( v > 102 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func99(uint8_t a1, uint8_t a2) {
+ char v = (a1 ^ a2);
+ if ( v > 96 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func100(uint8_t a1, uint8_t a2, uint8_t a3) {
+ char v = ((a1 ^ a2)) | a3;
+ if ( v != 127 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func101(uint8_t a1) {
+ char v = 4 * a1;
+ if ( v > 1 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func102(uint8_t a1, uint8_t a2) {
+ char v = a1 | a2;
+ if ( v <= 43 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func103(uint8_t a1, uint8_t a2) {
+ char v = (a1 & a2);
+ if ( v > 95 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func104(uint8_t a1, uint8_t a2, uint8_t a3) {
+ char v = (((a1 ^ a2))) & a3;
+ if ( v <= 2 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func105(uint8_t a1, uint8_t a2) {
+ char v = (a1 & a2);
+ if ( v > 65 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func106(uint8_t a1, uint8_t a2) {
+ char v = (a1 ^ a2);
+ if ( v <= 24 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func107(uint8_t a1) {
+ char v = ~a1;
+ if ( v > 1 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func108(uint8_t a1, uint8_t a2) {
+ char v = (a1 ^ a2);
+ if ( v > 67 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func109(uint8_t a1) {
+ char v = 2 * a1;
+ if ( v > 1 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func110(uint8_t a1, uint8_t a2) {
+ char v = (a1 & a2);
+ if ( v > 101 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func111(uint8_t a1, uint8_t a2, uint8_t a3) {
+ char v = ((a1 & a2)) | a3;
+ if ( v <= 121 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func112(uint8_t a1, uint8_t a2) {
+ char v = (a1 ^ a2);
+ if ( v <= 40 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func113(uint8_t a1, uint8_t a2) {
+ char v = (a1 & a2);
+ if ( v > 50 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func114(uint8_t a1) {
+ char v = a1 << 6;
+ if ( v > 1 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func115(uint8_t a1, uint8_t a2) {
+ char v = a1 | a2;
+ if ( v <= 12 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func116(uint8_t a1) {
+ char v = ~a1;
+ if ( v > 1 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func117(uint8_t a1) {
+ char v = a1 >> 5;
+ if ( v > 79 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func118(uint8_t a1) {
+ char v = ~a1;
+ if ( v > 1 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func119(uint8_t a1, uint8_t a2) {
+ char v = (a1 ^ a2);
+ if ( v > 44 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func120(uint8_t a1, uint8_t a2, uint8_t a3) {
+ char v = ((a1 & a2)) | a3;
+ if ( v <= 28 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func121(uint8_t a1, uint8_t a2) {
+ char v = a1 | a2;
+ if ( v <= 93 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func122(uint8_t a1, uint8_t a2) {
+ char v = a1 | a2;
+ if ( v <= 40 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func123(uint8_t a1) {
+ char v = ~a1;
+ if ( v > 1 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func124(uint8_t a1) {
+ char v = a1 >> 5;
+ if ( v <= 0 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func125(uint8_t a1) {
+ char v = ~a1;
+ if ( v > 1 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func126(uint8_t a1) {
+ char v = ~a1;
+ if ( v > 1 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func127(uint8_t a1, uint8_t a2) {
+ char v = (a1 ^ a2);
+ if ( v > 8 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func128(uint8_t a1) {
+ char v = ~a1;
+ if ( v > 1 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func129(uint8_t a1, uint8_t a2) {
+ char v = (a1 ^ a2);
+ if ( v <= 3 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func130(uint8_t a1, uint8_t a2) {
+ char v = a1 | a2;
+ if ( v <= 102 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func131(uint8_t a1, uint8_t a2) {
+ char v = (a1 ^ a2);
+ if ( v > 68 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func132(uint8_t a1, uint8_t a2) {
+ char v = (a1 & a2);
+ if ( v > 73 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func133(uint8_t a1, uint8_t a2) {
+ char v = (a1 & a2);
+ if ( v <= 68 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func134(uint8_t a1) {
+ char v = 16 * a1;
+ if ( v > 125 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func135(uint8_t a1, uint8_t a2) {
+ char v = (a1 ^ a2);
+ if ( v > 79 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func136(uint8_t a1, uint8_t a2) {
+ char v = (a1 ^ a2);
+ if ( v > 6 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func137(uint8_t a1, uint8_t a2) {
+ char v = (a1 & a2);
+ if ( v <= 16 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func138(uint8_t a1) {
+ char v = ~a1;
+ if ( v > 1 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func139(uint8_t a1) {
+ char v = ~a1;
+ if ( v > 1 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func140(uint8_t a1) {
+ char v = a1 >> 5;
+ if ( v > 74 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func141(uint8_t a1) {
+ char v = ~a1;
+ if ( v > 1 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func142(uint8_t a1, uint8_t a2) {
+ char v = a1 | a2;
+ if ( v <= 89 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func143(uint8_t a1, uint8_t a2) {
+ char v = (a1 ^ a2);
+ if ( v > 46 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func144(uint8_t a1) {
+ char v = 16 * a1;
+ if ( v <= 29 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func145(uint8_t a1, uint8_t a2) {
+ char v = a1 | a2;
+ if ( v <= 77 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func146(uint8_t a1, uint8_t a2) {
+ char v = (a1 ^ a2);
+ if ( v > 12 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func147(uint8_t a1) {
+ char v = ~a1;
+ if ( v > 1 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func148(uint8_t a1) {
+ char v = a1 >> 5;
+ if ( v > 27 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func149(uint8_t a1) {
+ char v = ~a1;
+ if ( v > 1 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func150(uint8_t a1, uint8_t a2) {
+ char v = a1 | a2;
+ if ( v > 122 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func151(uint8_t a1, uint8_t a2) {
+ char v = (a1 ^ a2);
+ if ( v <= 3 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func152(uint8_t a1, uint8_t a2) {
+ char v = (a1 & a2);
+ if ( v <= 56 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func153(uint8_t a1) {
+ char v = 16 * a1;
+ if ( v <= 3 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func154(uint8_t a1, uint8_t a2) {
+ char v = (a1 ^ a2);
+ if ( v > 43 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func155(uint8_t a1, uint8_t a2) {
+ char v = (a1 ^ a2);
+ if ( v <= 16 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func156(uint8_t a1) {
+ char v = ~a1;
+ if ( v > 1 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func157(uint8_t a1) {
+ char v = ~a1;
+ if ( v > 1 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func158(uint8_t a1) {
+ char v = ~a1;
+ if ( v > 1 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func159(uint8_t a1) {
+ char v = a1 >> 5;
+ if ( v > 88 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func160(uint8_t a1) {
+ char v = ~a1;
+ if ( v > 33 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func161(uint8_t a1, uint8_t a2) {
+ char v = (a1 ^ a2);
+ if ( v > 46 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func162(uint8_t a1) {
+ char v = ~a1;
+ if ( v > 1 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func163(uint8_t a1, uint8_t a2, uint8_t a3) {
+ char v = ((a1 & a2)) | a3;
+ if ( v <= 9 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func164(uint8_t a1, uint8_t a2) {
+ char v = (a1 ^ a2);
+ if ( v > 96 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func165(uint8_t a1) {
+ char v = ~a1;
+ if ( v > 1 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func166(uint8_t a1) {
+ char v = ~a1;
+ if ( v > 1 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func167(uint8_t a1) {
+ char v = a1 >> 5;
+ if ( v > 91 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func168(uint8_t a1) {
+ char v = ~a1;
+ if ( v > 1 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func169(uint8_t a1, uint8_t a2) {
+ char v = a1 | a2;
+ if ( v <= 32 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func170(uint8_t a1, uint8_t a2) {
+ char v = (a1 & a2);
+ if ( v <= 32 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func171(uint8_t a1) {
+ char v = ~a1;
+ if ( v > 1 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func172(uint8_t a1) {
+ char v = ~a1;
+ if ( v > 1 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func173(uint8_t a1) {
+ char v = ~a1;
+ if ( v > 1 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func174(uint8_t a1, uint8_t a2) {
+ char v = a1 | a2;
+ if ( v <= 90 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func175(uint8_t a1, uint8_t a2) {
+ char v = (a1 ^ a2);
+ if ( v > 32 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func176(uint8_t a1) {
+ char v = 16 * a1;
+ if ( v <= 61 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func177(uint8_t a1, uint8_t a2) {
+ char v = (a1 ^ a2);
+ if ( v <= 33 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func178(uint8_t a1) {
+ char v = a1 >> 5;
+ if ( v > 16 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func179(uint8_t a1) {
+ char v = ~a1;
+ if ( v > 64 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func180(uint8_t a1, uint8_t a2) {
+ char v = a1 | a2;
+ if ( v <= 95 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func181(uint8_t a1, uint8_t a2) {
+ char v = (a1 ^ a2);
+ if ( v > 48 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func182(uint8_t a1, uint8_t a2) {
+ char v = (a1 & a2);
+ if ( v > 113 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func183(uint8_t a1, uint8_t a2) {
+ char v = (a1 ^ a2);
+ if ( v <= 41 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func184(uint8_t a1) {
+ char v = 16 * a1;
+ if ( v <= 63 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func185(uint8_t a1) {
+ char v = ~a1;
+ if ( v > 1 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func186(uint8_t a1, uint8_t a2) {
+ char v = (a1 & a2);
+ if ( v <= 94 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func187(uint8_t a1, uint8_t a2) {
+ char v = (a1 ^ a2);
+ if ( v > 43 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func188(uint8_t a1) {
+ char v = (char)a1 >> 1;
+ if ( v <= 57 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func189(uint8_t a1) {
+ char v = ~a1;
+ if ( v > 1 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func190(uint8_t a1, uint8_t a2) {
+ char v = (a1 & a2);
+ if ( v > 103 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func191(uint8_t a1) {
+ char v = (char)a1 >> 1;
+ if ( v > 92 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func192(uint8_t a1) {
+ char v = ~a1;
+ if ( v > 1 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func193(uint8_t a1, uint8_t a2, uint8_t a3) {
+ char v = ((a1 & a2)) | a3;
+ if ( v <= 16 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func194(uint8_t a1, uint8_t a2) {
+ char v = a1 | a2;
+ if ( v <= 20 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func195(uint8_t a1, uint8_t a2) {
+ char v = (a1 ^ a2);
+ if ( v > 82 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func196(uint8_t a1, uint8_t a2) {
+ char v = a1 | a2;
+ if ( v > 117 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func197(uint8_t a1, uint8_t a2) {
+ char v = (a1 & a2);
+ if ( v <= 50 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func198(uint8_t a1, uint8_t a2) {
+ char v = (a1 ^ a2);
+ if ( v > 118 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func199(uint8_t a1, uint8_t a2) {
+ char v = (a1 ^ a2);
+ if ( v == 127 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func200(uint8_t a1) {
+ char v = ~a1;
+ if ( v > 1 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func201(uint8_t a1, uint8_t a2) {
+ char v = (a1 & a2);
+ if ( v <= 67 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func202(uint8_t a1, uint8_t a2) {
+ char v = (a1 & a2);
+ if ( v <= 56 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func203(uint8_t a1) {
+ char v = (char)a1 >> 1;
+ if ( v > 95 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func204(uint8_t a1) {
+ char v = ~a1;
+ if ( v > 1 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func205(uint8_t a1, uint8_t a2, uint8_t a3) {
+ char v = ((a1 ^ a2)) | a3;
+ if ( v > 95 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func206(uint8_t a1, uint8_t a2) {
+ char v = (a1 & a2);
+ if ( v <= 78 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func207(uint8_t a1) {
+ char v = (char)a1 >> 1;
+ if ( v <= 7 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func208(uint8_t a1) {
+ char v = a1 >> 5;
+ if ( v > 123 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func209(uint8_t a1) {
+ char v = ~a1;
+ if ( v > 1 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func210(uint8_t a1, uint8_t a2) {
+ char v = a1 | a2;
+ if ( v <= 101 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func211(uint8_t a1, uint8_t a2) {
+ char v = (a1 & a2);
+ if ( v <= 61 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func212(uint8_t a1) {
+ char v = 16 * a1;
+ if ( v <= 73 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func213(uint8_t a1, uint8_t a2) {
+ char v = (a1 ^ a2);
+ if ( v <= 34 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func214(uint8_t a1) {
+ char v = ~a1;
+ if ( v > 1 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func215(uint8_t a1, uint8_t a2) {
+ char v = (a1 & a2);
+ if ( v <= 5 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func216(uint8_t a1) {
+ char v = ~a1;
+ if ( v > 85 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func217(uint8_t a1, uint8_t a2) {
+ char v = (a1 & a2);
+ if ( v > 113 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func218(uint8_t a1) {
+ char v = (char)a1 >> 1;
+ if ( v > 61 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func219(uint8_t a1) {
+ char v = (char)a1 >> 1;
+ if ( v > 90 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func220(uint8_t a1) {
+ char v = a1 >> 5;
+ if ( v > 106 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func221(uint8_t a1) {
+ char v = ~a1;
+ if ( v > 1 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func222(uint8_t a1, uint8_t a2) {
+ char v = (a1 ^ a2);
+ if ( v > 84 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func223(uint8_t a1, uint8_t a2) {
+ char v = (a1 & a2);
+ if ( v > 81 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func224(uint8_t a1) {
+ char v = ~a1;
+ if ( v > 1 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func225(uint8_t a1) {
+ char v = a1 >> 5;
+ if ( v > 49 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func226(uint8_t a1) {
+ char v = ~a1;
+ if ( v > 1 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func227(uint8_t a1, uint8_t a2) {
+ char v = (a1 ^ a2);
+ if ( v > 66 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func228(uint8_t a1, uint8_t a2) {
+ char v = (a1 & a2);
+ if ( v > 81 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func229(uint8_t a1, uint8_t a2) {
+ char v = (a1 & a2);
+ if ( v > 41 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func230(uint8_t a1, uint8_t a2) {
+ char v = (a1 ^ a2);
+ if ( v > 82 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func231(uint8_t a1, uint8_t a2) {
+ char v = (a1 & a2);
+ if ( v > 84 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func232(uint8_t a1, uint8_t a2) {
+ char v = (a1 & a2);
+ if ( v <= 34 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func233(uint8_t a1, uint8_t a2) {
+ char v = (a1 & a2);
+ if ( v > 66 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func234(uint8_t a1, uint8_t a2) {
+ char v = (a1 & a2);
+ if ( v > 90 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func235(uint8_t a1, uint8_t a2) {
+ char v = (a1 & a2);
+ if ( v > 73 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func236(uint8_t a1, uint8_t a2) {
+ char v = (a1 & a2);
+ if ( v <= 12 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func237(uint8_t a1, uint8_t a2) {
+ char v = (a1 ^ a2);
+ if ( v <= 9 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func238(uint8_t a1, uint8_t a2) {
+ char v = (a1 ^ a2);
+ if ( v <= 42 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func239(uint8_t a1, uint8_t a2) {
+ char v = (a1 ^ a2);
+ if ( v > 44 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func240(uint8_t a1, uint8_t a2) {
+ char v = (a1 & a2);
+ if ( v <= 14 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func241(uint8_t a1, uint8_t a2) {
+ char v = (a1 & a2);
+ if ( v <= 16 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func242(uint8_t a1, uint8_t a2) {
+ char v = (a1 & a2);
+ if ( v > 74 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func243(uint8_t a1, uint8_t a2) {
+ char v = (a1 ^ a2);
+ if ( v > 102 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func244(uint8_t a1) {
+ char v = 4 * a1;
+ if ( v <= 16 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func245(uint8_t a1, uint8_t a2) {
+ char v = a1 | a2;
+ if ( v <= 87 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func246(uint8_t a1, uint8_t a2) {
+ char v = (a1 ^ a2);
+ if ( v > 29 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func247(uint8_t a1, uint8_t a2) {
+ char v = (a1 & a2);
+ if ( v > 51 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func248(uint8_t a1, uint8_t a2) {
+ char v = (a1 ^ a2);
+ if ( v > 74 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func249(uint8_t a1) {
+ char v = 4 * a1;
+ if ( v <= 103 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func250(uint8_t a1, uint8_t a2) {
+ char v = a1 | a2;
+ if ( v <= 56 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func251(uint8_t a1, uint8_t a2) {
+ char v = (a1 ^ a2);
+ if ( v <= 11 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func252(uint8_t a1, uint8_t a2) {
+ char v = (a1 & a2);
+ if ( v <= 16 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func253(uint8_t a1, uint8_t a2) {
+ char v = (a1 & a2);
+ if ( v <= 22 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func254(uint8_t a1, uint8_t a2, uint8_t a3) {
+ char v = ((a1 & a2)) | a3;
+ if ( v > 122 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func255(uint8_t a1, uint8_t a2) {
+ char v = (a1 ^ a2);
+ if ( v > 74 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func256(uint8_t a1) {
+ char v = 4 * a1;
+ if ( v <= 16 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func257(uint8_t a1, uint8_t a2) {
+ char v = (a1 ^ a2);
+ if ( v > 67 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func258(uint8_t a1, uint8_t a2) {
+ char v = (a1 & a2);
+ if ( v > 102 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func259(uint8_t a1, uint8_t a2) {
+ char v = (a1 ^ a2);
+ if ( v > 74 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func260(uint8_t a1, uint8_t a2) {
+ char v = a1 | a2;
+ if ( v <= 27 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func261(uint8_t a1) {
+ char v = 4 * a1;
+ if ( v <= 58 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func262(uint8_t a1) {
+ char v = 4 * a1;
+ if ( v <= 77 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func263(uint8_t a1, uint8_t a2) {
+ char v = a1 | a2;
+ if ( v <= 3 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func264(uint8_t a1, uint8_t a2) {
+ char v = (a1 & a2);
+ if ( v <= 13 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func265(uint8_t a1, uint8_t a2) {
+ char v = (a1 ^ a2);
+ if ( v > 47 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func266(uint8_t a1, uint8_t a2) {
+ char v = (a1 & a2);
+ if ( v <= 39 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func267(uint8_t a1, uint8_t a2) {
+ char v = a1 | a2;
+ if ( v == 127 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func268(uint8_t a1, uint8_t a2) {
+ char v = a1 | a2;
+ if ( v <= 66 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func269(uint8_t a1, uint8_t a2) {
+ char v = (a1 & a2);
+ if ( v <= 47 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func270(uint8_t a1, uint8_t a2) {
+ char v = (a1 & a2);
+ if ( v > 63 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func271(uint8_t a1, uint8_t a2) {
+ char v = (a1 & a2);
+ if ( v > 122 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func272(uint8_t a1) {
+ char v = 4 * a1;
+ if ( v <= 65 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func273(uint8_t a1, uint8_t a2) {
+ char v = (a1 & a2);
+ if ( v > 120 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func274(uint8_t a1) {
+ char v = 4 * a1;
+ if ( v <= 83 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func275(uint8_t a1, uint8_t a2) {
+ char v = a1 | a2;
+ if ( v <= 99 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func276(uint8_t a1) {
+ char v = ~a1;
+ if ( v > 1 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func277(uint8_t a1) {
+ char v = a1 >> 5;
+ if ( v > 42 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func278(uint8_t a1) {
+ char v = ~a1;
+ if ( v > 1 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func279(uint8_t a1, uint8_t a2) {
+ char v = (a1 ^ a2);
+ if ( v > 110 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func280(uint8_t a1) {
+ char v = 4 * a1;
+ if ( v <= 92 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func281(uint8_t a1, uint8_t a2) {
+ char v = a1 | a2;
+ if ( v <= 59 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func282(uint8_t a1, uint8_t a2) {
+ char v = a1 | a2;
+ if ( v <= 1 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func283(uint8_t a1) {
+ char v = ~a1;
+ if ( v > 1 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func284(uint8_t a1) {
+ char v = ~a1;
+ if ( v > 1 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func285(uint8_t a1) {
+ char v = ~a1;
+ if ( v > 17 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func286(uint8_t a1) {
+ char v = ~a1;
+ if ( v > 1 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func287(uint8_t a1, uint8_t a2) {
+ char v = a1 | a2;
+ if ( v <= 78 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func288(uint8_t a1, uint8_t a2) {
+ char v = (a1 ^ a2);
+ if ( v > 47 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func289(uint8_t a1, uint8_t a2) {
+ char v = (a1 & a2);
+ if ( v <= 90 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func290(uint8_t a1) {
+ char v = 16 * a1;
+ if ( v <= 78 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func291(uint8_t a1, uint8_t a2) {
+ char v = (a1 ^ a2);
+ if ( v <= 30 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func292(uint8_t a1) {
+ char v = ~a1;
+ if ( v > 1 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func293(uint8_t a1) {
+ char v = ~a1;
+ if ( v > 1 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func294(uint8_t a1) {
+ char v = ~a1;
+ if ( v > 1 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func295(uint8_t a1, uint8_t a2) {
+ char v = a1 | a2;
+ if ( v <= 17 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func296(uint8_t a1, uint8_t a2) {
+ char v = (a1 ^ a2);
+ if ( v > 86 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func297(uint8_t a1, uint8_t a2) {
+ char v = (a1 & a2);
+ if ( v > 120 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func298(uint8_t a1) {
+ char v = 16 * a1;
+ if ( v <= 46 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func299(uint8_t a1, uint8_t a2) {
+ char v = (a1 ^ a2);
+ if ( v > 63 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func300(uint8_t a1, uint8_t a2) {
+ char v = (a1 ^ a2);
+ if ( v <= 5 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func301(uint8_t a1) {
+ char v = ~a1;
+ if ( v > 17 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func302(uint8_t a1) {
+ char v = ~a1;
+ if ( v > 113 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func303(uint8_t a1) {
+ char v = ~a1;
+ if ( v > 1 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func304(uint8_t a1, uint8_t a2) {
+ char v = a1 | a2;
+ if ( v <= 73 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func305(uint8_t a1, uint8_t a2) {
+ char v = (a1 ^ a2);
+ if ( v > 60 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func306(uint8_t a1, uint8_t a2) {
+ char v = (a1 & a2);
+ if ( v > 119 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func307(uint8_t a1) {
+ char v = ~a1;
+ if ( v > 21 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func308(uint8_t a1) {
+ char v = ~a1;
+ if ( v > 107 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func309(uint8_t a1, uint8_t a2) {
+ char v = (a1 ^ a2);
+ if ( v > 44 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func310(uint8_t a1, uint8_t a2) {
+ char v = (a1 & a2);
+ if ( v <= 57 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func311(uint8_t a1, uint8_t a2) {
+ char v = (a1 ^ a2);
+ if ( v > 59 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func312(uint8_t a1) {
+ char v = ~a1;
+ if ( v > 1 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func313(uint8_t a1) {
+ char v = ~a1;
+ if ( v > 1 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func314(uint8_t a1) {
+ char v = a1 >> 5;
+ if ( v > 58 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func315(uint8_t a1) {
+ char v = ~a1;
+ if ( v > 1 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func316(uint8_t a1, uint8_t a2) {
+ char v = a1 | a2;
+ if ( v <= 101 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func317(uint8_t a1, uint8_t a2) {
+ char v = (a1 & a2);
+ if ( v <= 99 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func318(uint8_t a1) {
+ char v = 16 * a1;
+ if ( v <= 78 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func319(uint8_t a1, uint8_t a2) {
+ char v = (a1 ^ a2);
+ if ( v > 16 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func320(uint8_t a1) {
+ char v = ~a1;
+ if ( v > 10 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func321(uint8_t a1) {
+ char v = ~a1;
+ if ( v > 1 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func322(uint8_t a1) {
+ char v = a1 >> 5;
+ if ( v > 3 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func323(uint8_t a1) {
+ char v = ~a1;
+ if ( v > 1 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func324(uint8_t a1, uint8_t a2) {
+ char v = a1 | a2;
+ if ( v > 118 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func325(uint8_t a1, uint8_t a2) {
+ char v = (a1 ^ a2);
+ if ( v <= 1 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func326(uint8_t a1) {
+ char v = 16 * a1;
+ if ( v <= 0 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func327(uint8_t a1, uint8_t a2) {
+ char v = (a1 ^ a2);
+ if ( v > 101 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func328(uint8_t a1) {
+ char v = a1 >> 5;
+ if ( v > 18 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func329(uint8_t a1) {
+ char v = ~a1;
+ if ( v > 1 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func330(uint8_t a1, uint8_t a2) {
+ char v = a1 | a2;
+ if ( v <= 0 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func331(uint8_t a1, uint8_t a2) {
+ char v = (a1 ^ a2);
+ if ( v > 67 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func332(uint8_t a1, uint8_t a2) {
+ char v = (a1 & a2);
+ if ( v > 103 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func333(uint8_t a1) {
+ char v = 16 * a1;
+ if ( v > 1 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func334(uint8_t a1, uint8_t a2) {
+ char v = (a1 ^ a2);
+ if ( v <= 38 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func335(uint8_t a1) {
+ char v = ~a1;
+ if ( v > 1 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func336(uint8_t a1, uint8_t a2) {
+ char v = (a1 & a2);
+ if ( v <= 94 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func337(uint8_t a1) {
+ char v = (char)a1 >> 1;
+ if ( v > 63 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func338(uint8_t a1) {
+ char v = ~a1;
+ if ( v > 1 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func339(uint8_t a1) {
+ char v = (char)a1 >> 1;
+ if ( v <= 47 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func340(uint8_t a1) {
+ char v = a1 >> 5;
+ if ( v <= 0 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func341(uint8_t a1) {
+ char v = ~a1;
+ if ( v > 1 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func342(uint8_t a1, uint8_t a2) {
+ char v = a1 | a2;
+ if ( v > 118 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func343(uint8_t a1, uint8_t a2) {
+ char v = (a1 ^ a2);
+ if ( v > 58 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func344(uint8_t a1, uint8_t a2) {
+ char v = (a1 & a2);
+ if ( v <= 91 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func345(uint8_t a1) {
+ char v = 16 * a1;
+ if ( v <= 72 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func346(uint8_t a1, uint8_t a2) {
+ char v = (a1 ^ a2);
+ if ( v > 63 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func347(uint8_t a1) {
+ char v = ~a1;
+ if ( v > 1 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func348(uint8_t a1, uint8_t a2) {
+ char v = (a1 & a2);
+ if ( v <= 94 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func349(uint8_t a1) {
+ char v = (char)a1 >> 1;
+ if ( v <= 57 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func350(uint8_t a1) {
+ char v = ~a1;
+ if ( v > 1 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func351(uint8_t a1, uint8_t a2) {
+ char v = (a1 & a2);
+ if ( v > 99 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func352(uint8_t a1) {
+ char v = (char)a1 >> 1;
+ if ( v > 63 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func353(uint8_t a1) {
+ char v = a1 >> 5;
+ if ( v > 81 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func354(uint8_t a1) {
+ char v = ~a1;
+ if ( v > 1 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func355(uint8_t a1, uint8_t a2) {
+ char v = a1 | a2;
+ if ( v > 118 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func356(uint8_t a1, uint8_t a2) {
+ char v = (a1 ^ a2);
+ if ( v > 1 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func357(uint8_t a1, uint8_t a2) {
+ char v = (a1 & a2);
+ if ( v <= 72 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func358(uint8_t a1) {
+ char v = 16 * a1;
+ if ( v > 1 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func359(uint8_t a1, uint8_t a2) {
+ char v = (a1 ^ a2);
+ if ( v > 110 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func360(uint8_t a1) {
+ char v = ~a1;
+ if ( v > 1 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func361(uint8_t a1, uint8_t a2) {
+ char v = (a1 & a2);
+ if ( v <= 68 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func362(uint8_t a1) {
+ char v = (char)a1 >> 1;
+ if ( v > 91 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func363(uint8_t a1) {
+ char v = ~a1;
+ if ( v > 1 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func364(uint8_t a1, uint8_t a2) {
+ char v = (a1 & a2);
+ if ( v > 99 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func365(uint8_t a1) {
+ char v = (char)a1 >> 1;
+ if ( v <= 40 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func366(uint8_t a1) {
+ char v = (char)a1 >> 1;
+ if ( v <= 31 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func367(uint8_t a1) {
+ char v = ~a1;
+ if ( v > 1 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func368(uint8_t a1) {
+ char v = a1 >> 5;
+ if ( v > 96 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func369(uint8_t a1) {
+ char v = ~a1;
+ if ( v > 1 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func370(uint8_t a1, uint8_t a2) {
+ char v = (a1 ^ a2);
+ if ( v > 42 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func371(uint8_t a1, uint8_t a2) {
+ char v = (a1 & a2);
+ if ( v > 118 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func372(uint8_t a1) {
+ char v = (char)a1 >> 1;
+ if ( v > 94 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func373(uint8_t a1) {
+ char v = ~a1;
+ if ( v > 1 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func374(uint8_t a1) {
+ char v = ~a1;
+ if ( v > 1 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func375(uint8_t a1, uint8_t a2) {
+ char v = (a1 ^ a2);
+ if ( v > 64 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func376(uint8_t a1, uint8_t a2) {
+ char v = (a1 & a2);
+ if ( v > 110 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func377(uint8_t a1) {
+ char v = 4 * a1;
+ if ( v <= 104 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func378(uint8_t a1, uint8_t a2) {
+ char v = a1 | a2;
+ if ( v > 112 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func379(uint8_t a1, uint8_t a2) {
+ char v = (a1 & a2);
+ if ( v <= 62 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func380(uint8_t a1, uint8_t a2) {
+ char v = (a1 & a2);
+ if ( v > 48 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func381(uint8_t a1, uint8_t a2) {
+ char v = (a1 ^ a2);
+ if ( v > 58 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func382(uint8_t a1) {
+ char v = 4 * a1;
+ if ( v <= 104 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func383(uint8_t a1, uint8_t a2) {
+ char v = a1 | a2;
+ if ( v <= 50 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func384(uint8_t a1, uint8_t a2) {
+ char v = (a1 & a2);
+ if ( v <= 38 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func385(uint8_t a1, uint8_t a2) {
+ char v = (a1 & a2);
+ if ( v > 85 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func386(uint8_t a1, uint8_t a2) {
+ char v = (a1 ^ a2);
+ if ( v <= 18 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func387(uint8_t a1) {
+ char v = 4 * a1;
+ if ( v <= 97 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func388(uint8_t a1, uint8_t a2) {
+ char v = a1 | a2;
+ if ( v <= 94 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func389(uint8_t a1, uint8_t a2) {
+ char v = (a1 & a2);
+ if ( v <= 26 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func390(uint8_t a1, uint8_t a2) {
+ char v = (a1 ^ a2);
+ if ( v > 67 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func391(uint8_t a1) {
+ char v = 4 * a1;
+ if ( v <= 103 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func392(uint8_t a1, uint8_t a2) {
+ char v = (a1 & a2);
+ if ( v > 50 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func393(uint8_t a1, uint8_t a2) {
+ char v = (a1 ^ a2);
+ if ( v <= 22 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func394(uint8_t a1) {
+ char v = 4 * a1;
+ if ( v <= 103 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func395(uint8_t a1, uint8_t a2) {
+ char v = a1 | a2;
+ if ( v <= 38 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func396(uint8_t a1, uint8_t a2) {
+ char v = (a1 & a2);
+ if ( v <= 52 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func397(uint8_t a1, uint8_t a2) {
+ char v = (a1 & a2);
+ if ( v <= 17 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func398(uint8_t a1) {
+ char v = 4 * a1;
+ if ( v > 1 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func399(uint8_t a1, uint8_t a2) {
+ char v = a1 | a2;
+ if ( v <= 92 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func400(uint8_t a1, uint8_t a2) {
+ char v = (a1 & a2);
+ if ( v <= 55 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func401(uint8_t a1, uint8_t a2) {
+ char v = (a1 ^ a2);
+ if ( v > 81 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func402(uint8_t a1) {
+ char v = 4 * a1;
+ if ( v > 1 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func403(uint8_t a1, uint8_t a2) {
+ char v = a1 | a2;
+ if ( v <= 94 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func404(uint8_t a1) {
+ char v = ~a1;
+ if ( v > 1 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func405(uint8_t a1) {
+ char v = ~a1;
+ if ( v > 1 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func406(uint8_t a1, uint8_t a2) {
+ char v = (a1 ^ a2);
+ if ( v > 101 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func407(uint8_t a1) {
+ char v = 4 * a1;
+ if ( v > 1 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func408(uint8_t a1, uint8_t a2) {
+ char v = a1 | a2;
+ if ( v <= 44 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func409(uint8_t a1) {
+ char v = ~a1;
+ if ( v > 1 )
+ return 0;
+ return 1;
+}
+
+__attribute__((noinline))
+int func410(uint8_t a1) {
+ char v = ~a1;
+ if ( v > 1 )
+ return 0;
+ return 1;
+}
+
+int api(const uint8_t *data, size_t size) {
+ if (size != 20) return 0;
+
+ if (func1(data[0], data[1]) == 0)
+ return 0;
+ if (func2(data[0], data[1]) == 0)
+ return 0;
+ if (func3(data[18], data[1]) == 0)
+ return 0;
+ if (func4(data[7], data[4], data[0]) == 0)
+ return 0;
+ if (func5(data[0], data[2]) == 0)
+ return 0;
+ if (func6(data[11], data[17]) == 0)
+ return 0;
+ if (func7(data[0], data[13]) == 0)
+ return 0;
+ if (func8(data[13], data[10]) == 0)
+ return 0;
+ if (func9(data[11], data[16]) == 0)
+ return 0;
+ if (func10(data[10], data[8]) == 0)
+ return 0;
+ if (func11(data[19], data[5]) == 0)
+ return 0;
+ if (func12(data[0], data[1]) == 0)
+ return 0;
+ if (func13(data[17], data[3]) == 0)
+ return 0;
+ if (func14(data[14]) == 0)
+ return 0;
+ if (func15(data[13], data[15]) == 0)
+ return 0;
+ if (func16(data[0]) == 0)
+ return 0;
+ if (func17(data[19]) == 0)
+ return 0;
+ if (func18(data[1], data[11]) == 0)
+ return 0;
+ if (func19(data[12], data[15]) == 0)
+ return 0;
+ if (func20(data[13], data[1]) == 0)
+ return 0;
+ if (func21(data[10], data[19], data[12]) == 0)
+ return 0;
+ if (func22(data[6]) == 0)
+ return 0;
+ if (func23(data[1], data[9]) == 0)
+ return 0;
+ if (func24(data[16]) == 0)
+ return 0;
+ if (func25(data[6]) == 0)
+ return 0;
+ if (func26(data[4], data[12]) == 0)
+ return 0;
+ if (func27(data[16]) == 0)
+ return 0;
+ if (func28(data[14]) == 0)
+ return 0;
+ if (func29(data[0]) == 0)
+ return 0;
+ if (func30(data[19]) == 0)
+ return 0;
+ if (func31(data[0], data[1]) == 0)
+ return 0;
+ if (func32(data[0], data[1]) == 0)
+ return 0;
+ if (func33(data[14]) == 0)
+ return 0;
+ if (func34(data[0], data[19]) == 0)
+ return 0;
+ if (func35(data[0]) == 0)
+ return 0;
+ if (func36(data[16], data[7]) == 0)
+ return 0;
+ if (func37(data[19]) == 0)
+ return 0;
+ if (func38(data[15], data[3]) == 0)
+ return 0;
+ if (func39(data[19], data[15]) == 0)
+ return 0;
+ if (func40(data[0], data[1]) == 0)
+ return 0;
+ if (func41(data[18], data[1]) == 0)
+ return 0;
+ if (func42(data[16], data[5], data[1]) == 0)
+ return 0;
+ if (func43(data[14]) == 0)
+ return 0;
+ if (func44(data[0]) == 0)
+ return 0;
+ if (func45(data[19]) == 0)
+ return 0;
+ if (func46(data[4], data[19]) == 0)
+ return 0;
+ if (func47(data[8], data[7]) == 0)
+ return 0;
+ if (func48(data[6], data[7]) == 0)
+ return 0;
+ if (func49(data[18], data[1]) == 0)
+ return 0;
+ if (func50(data[2], data[8]) == 0)
+ return 0;
+ if (func51(data[2], data[13]) == 0)
+ return 0;
+ if (func52(data[3], data[8]) == 0)
+ return 0;
+ if (func53(data[16], data[18]) == 0)
+ return 0;
+ if (func54(data[10], data[9]) == 0)
+ return 0;
+ if (func55(data[18], data[1]) == 0)
+ return 0;
+ if (func56(data[0], data[1]) == 0)
+ return 0;
+ if (func57(data[16], data[1]) == 0)
+ return 0;
+ if (func58(data[18], data[1]) == 0)
+ return 0;
+ if (func59(data[18], data[3]) == 0)
+ return 0;
+ if (func60(data[9], data[1]) == 0)
+ return 0;
+ if (func61(data[0], data[1]) == 0)
+ return 0;
+ if (func62(data[13], data[1]) == 0)
+ return 0;
+ if (func63(data[18], data[1]) == 0)
+ return 0;
+ if (func64(data[0], data[1]) == 0)
+ return 0;
+ if (func65(data[0], data[1]) == 0)
+ return 0;
+ if (func66(data[11], data[14]) == 0)
+ return 0;
+ if (func67(data[5], data[11]) == 0)
+ return 0;
+ if (func68(data[18], data[1]) == 0)
+ return 0;
+ if (func69(data[0], data[6]) == 0)
+ return 0;
+ if (func70(data[2]) == 0)
+ return 0;
+ if (func71(data[0], data[1]) == 0)
+ return 0;
+ if (func72(data[9], data[10]) == 0)
+ return 0;
+ if (func73(data[10], data[8]) == 0)
+ return 0;
+ if (func74(data[19], data[17]) == 0)
+ return 0;
+ if (func75(data[0], data[17], data[8]) == 0)
+ return 0;
+ if (func76(data[17], data[18]) == 0)
+ return 0;
+ if (func77(data[18], data[9]) == 0)
+ return 0;
+ if (func78(data[3], data[6]) == 0)
+ return 0;
+ if (func79(data[16]) == 0)
+ return 0;
+ if (func80(data[7], data[3], data[17]) == 0)
+ return 0;
+ if (func81(data[0], data[1]) == 0)
+ return 0;
+ if (func82(data[10], data[18]) == 0)
+ return 0;
+ if (func83(data[6], data[7]) == 0)
+ return 0;
+ if (func84(data[0], data[6]) == 0)
+ return 0;
+ if (func85(data[12]) == 0)
+ return 0;
+ if (func86(data[0], data[1]) == 0)
+ return 0;
+ if (func87(data[6], data[1]) == 0)
+ return 0;
+ if (func88(data[18], data[1]) == 0)
+ return 0;
+ if (func89(data[0], data[6]) == 0)
+ return 0;
+ if (func90(data[0], data[1]) == 0)
+ return 0;
+ if (func91(data[18], data[1]) == 0)
+ return 0;
+ if (func92(data[0], data[6]) == 0)
+ return 0;
+ if (func93(data[13], data[10]) == 0)
+ return 0;
+ if (func94(data[2]) == 0)
+ return 0;
+ if (func95(data[0], data[1]) == 0)
+ return 0;
+ if (func96(data[0], data[11]) == 0)
+ return 0;
+ if (func97(data[18], data[1]) == 0)
+ return 0;
+ if (func98(data[0], data[6]) == 0)
+ return 0;
+ if (func99(data[0], data[19]) == 0)
+ return 0;
+ if (func100(data[14], data[18], data[3]) == 0)
+ return 0;
+ if (func101(data[14]) == 0)
+ return 0;
+ if (func102(data[6], data[1]) == 0)
+ return 0;
+ if (func103(data[5], data[1]) == 0)
+ return 0;
+ if (func104(data[14], data[3], data[10]) == 0)
+ return 0;
+ if (func105(data[18], data[1]) == 0)
+ return 0;
+ if (func106(data[0], data[6]) == 0)
+ return 0;
+ if (func107(data[6]) == 0)
+ return 0;
+ if (func108(data[9], data[10]) == 0)
+ return 0;
+ if (func109(data[7]) == 0)
+ return 0;
+ if (func110(data[9], data[17]) == 0)
+ return 0;
+ if (func111(data[16], data[15], data[18]) == 0)
+ return 0;
+ if (func112(data[0], data[16]) == 0)
+ return 0;
+ if (func113(data[18], data[3]) == 0)
+ return 0;
+ if (func114(data[3]) == 0)
+ return 0;
+ if (func115(data[0], data[1]) == 0)
+ return 0;
+ if (func116(data[14]) == 0)
+ return 0;
+ if (func117(data[0]) == 0)
+ return 0;
+ if (func118(data[19]) == 0)
+ return 0;
+ if (func119(data[0], data[6]) == 0)
+ return 0;
+ if (func120(data[9], data[5], data[0]) == 0)
+ return 0;
+ if (func121(data[0], data[1]) == 0)
+ return 0;
+ if (func122(data[12], data[4]) == 0)
+ return 0;
+ if (func123(data[14]) == 0)
+ return 0;
+ if (func124(data[0]) == 0)
+ return 0;
+ if (func125(data[19]) == 0)
+ return 0;
+ if (func126(data[14]) == 0)
+ return 0;
+ if (func127(data[1], data[9]) == 0)
+ return 0;
+ if (func128(data[19]) == 0)
+ return 0;
+ if (func129(data[11], data[14]) == 0)
+ return 0;
+ if (func130(data[11], data[9]) == 0)
+ return 0;
+ if (func131(data[12], data[15]) == 0)
+ return 0;
+ if (func132(data[0], data[2]) == 0)
+ return 0;
+ if (func133(data[13], data[1]) == 0)
+ return 0;
+ if (func134(data[7]) == 0)
+ return 0;
+ if (func135(data[13], data[5]) == 0)
+ return 0;
+ if (func136(data[12], data[14]) == 0)
+ return 0;
+ if (func137(data[9], data[4]) == 0)
+ return 0;
+ if (func138(data[6]) == 0)
+ return 0;
+ if (func139(data[14]) == 0)
+ return 0;
+ if (func140(data[0]) == 0)
+ return 0;
+ if (func141(data[19]) == 0)
+ return 0;
+ if (func142(data[11], data[9]) == 0)
+ return 0;
+ if (func143(data[12], data[15]) == 0)
+ return 0;
+ if (func144(data[7]) == 0)
+ return 0;
+ if (func145(data[19], data[7]) == 0)
+ return 0;
+ if (func146(data[4], data[6]) == 0)
+ return 0;
+ if (func147(data[6]) == 0)
+ return 0;
+ if (func148(data[0]) == 0)
+ return 0;
+ if (func149(data[19]) == 0)
+ return 0;
+ if (func150(data[11], data[9]) == 0)
+ return 0;
+ if (func151(data[12], data[15]) == 0)
+ return 0;
+ if (func152(data[13], data[1]) == 0)
+ return 0;
+ if (func153(data[7]) == 0)
+ return 0;
+ if (func154(data[2], data[8]) == 0)
+ return 0;
+ if (func155(data[13], data[5]) == 0)
+ return 0;
+ if (func156(data[6]) == 0)
+ return 0;
+ if (func157(data[6]) == 0)
+ return 0;
+ if (func158(data[14]) == 0)
+ return 0;
+ if (func159(data[0]) == 0)
+ return 0;
+ if (func160(data[19]) == 0)
+ return 0;
+ if (func161(data[12], data[15]) == 0)
+ return 0;
+ if (func162(data[5]) == 0)
+ return 0;
+ if (func163(data[6], data[7], data[3]) == 0)
+ return 0;
+ if (func164(data[13], data[5]) == 0)
+ return 0;
+ if (func165(data[6]) == 0)
+ return 0;
+ if (func166(data[14]) == 0)
+ return 0;
+ if (func167(data[0]) == 0)
+ return 0;
+ if (func168(data[19]) == 0)
+ return 0;
+ if (func169(data[11], data[9]) == 0)
+ return 0;
+ if (func170(data[9], data[11]) == 0)
+ return 0;
+ if (func171(data[6]) == 0)
+ return 0;
+ if (func172(data[14]) == 0)
+ return 0;
+ if (func173(data[19]) == 0)
+ return 0;
+ if (func174(data[11], data[9]) == 0)
+ return 0;
+ if (func175(data[12], data[15]) == 0)
+ return 0;
+ if (func176(data[7]) == 0)
+ return 0;
+ if (func177(data[13], data[5]) == 0)
+ return 0;
+ if (func178(data[0]) == 0)
+ return 0;
+ if (func179(data[19]) == 0)
+ return 0;
+ if (func180(data[11], data[9]) == 0)
+ return 0;
+ if (func181(data[12], data[15]) == 0)
+ return 0;
+ if (func182(data[13], data[1]) == 0)
+ return 0;
+ if (func183(data[7], data[17]) == 0)
+ return 0;
+ if (func184(data[7]) == 0)
+ return 0;
+ if (func185(data[6]) == 0)
+ return 0;
+ if (func186(data[4], data[12]) == 0)
+ return 0;
+ if (func187(data[2], data[8]) == 0)
+ return 0;
+ if (func188(data[16]) == 0)
+ return 0;
+ if (func189(data[6]) == 0)
+ return 0;
+ if (func190(data[4], data[12]) == 0)
+ return 0;
+ if (func191(data[16]) == 0)
+ return 0;
+ if (func192(data[19]) == 0)
+ return 0;
+ if (func193(data[19], data[4], data[2]) == 0)
+ return 0;
+ if (func194(data[11], data[9]) == 0)
+ return 0;
+ if (func195(data[12], data[15]) == 0)
+ return 0;
+ if (func196(data[13], data[15]) == 0)
+ return 0;
+ if (func197(data[13], data[1]) == 0)
+ return 0;
+ if (func198(data[19], data[5]) == 0)
+ return 0;
+ if (func199(data[13], data[5]) == 0)
+ return 0;
+ if (func200(data[6]) == 0)
+ return 0;
+ if (func201(data[4], data[12]) == 0)
+ return 0;
+ if (func202(data[5], data[17]) == 0)
+ return 0;
+ if (func203(data[16]) == 0)
+ return 0;
+ if (func204(data[6]) == 0)
+ return 0;
+ if (func205(data[7], data[3], data[17]) == 0)
+ return 0;
+ if (func206(data[4], data[12]) == 0)
+ return 0;
+ if (func207(data[16]) == 0)
+ return 0;
+ if (func208(data[0]) == 0)
+ return 0;
+ if (func209(data[19]) == 0)
+ return 0;
+ if (func210(data[11], data[9]) == 0)
+ return 0;
+ if (func211(data[13], data[1]) == 0)
+ return 0;
+ if (func212(data[7]) == 0)
+ return 0;
+ if (func213(data[13], data[5]) == 0)
+ return 0;
+ if (func214(data[6]) == 0)
+ return 0;
+ if (func215(data[4], data[12]) == 0)
+ return 0;
+ if (func216(data[6]) == 0)
+ return 0;
+ if (func217(data[4], data[12]) == 0)
+ return 0;
+ if (func218(data[16]) == 0)
+ return 0;
+ if (func219(data[16]) == 0)
+ return 0;
+ if (func220(data[0]) == 0)
+ return 0;
+ if (func221(data[19]) == 0)
+ return 0;
+ if (func222(data[0], data[1]) == 0)
+ return 0;
+ if (func223(data[0], data[1]) == 0)
+ return 0;
+ if (func224(data[14]) == 0)
+ return 0;
+ if (func225(data[0]) == 0)
+ return 0;
+ if (func226(data[19]) == 0)
+ return 0;
+ if (func227(data[0], data[1]) == 0)
+ return 0;
+ if (func228(data[0], data[1]) == 0)
+ return 0;
+ if (func229(data[18], data[1]) == 0)
+ return 0;
+ if (func230(data[0], data[1]) == 0)
+ return 0;
+ if (func231(data[17], data[3]) == 0)
+ return 0;
+ if (func232(data[0], data[1]) == 0)
+ return 0;
+ if (func233(data[18], data[1]) == 0)
+ return 0;
+ if (func234(data[0], data[1]) == 0)
+ return 0;
+ if (func235(data[18], data[4]) == 0)
+ return 0;
+ if (func236(data[18], data[1]) == 0)
+ return 0;
+ if (func237(data[0], data[1]) == 0)
+ return 0;
+ if (func238(data[2], data[8]) == 0)
+ return 0;
+ if (func239(data[13], data[0]) == 0)
+ return 0;
+ if (func240(data[0], data[1]) == 0)
+ return 0;
+ if (func241(data[0], data[1]) == 0)
+ return 0;
+ if (func242(data[18], data[1]) == 0)
+ return 0;
+ if (func243(data[0], data[6]) == 0)
+ return 0;
+ if (func244(data[2]) == 0)
+ return 0;
+ if (func245(data[0], data[1]) == 0)
+ return 0;
+ if (func246(data[1], data[11]) == 0)
+ return 0;
+ if (func247(data[18], data[1]) == 0)
+ return 0;
+ if (func248(data[0], data[6]) == 0)
+ return 0;
+ if (func249(data[2]) == 0)
+ return 0;
+ if (func250(data[0], data[1]) == 0)
+ return 0;
+ if (func251(data[4], data[6]) == 0)
+ return 0;
+ if (func252(data[0], data[1]) == 0)
+ return 0;
+ if (func253(data[18], data[1]) == 0)
+ return 0;
+ if (func254(data[16], data[15], data[18]) == 0)
+ return 0;
+ if (func255(data[0], data[6]) == 0)
+ return 0;
+ if (func256(data[2]) == 0)
+ return 0;
+ if (func257(data[16], data[18]) == 0)
+ return 0;
+ if (func258(data[0], data[1]) == 0)
+ return 0;
+ if (func259(data[0], data[6]) == 0)
+ return 0;
+ if (func260(data[9], data[13]) == 0)
+ return 0;
+ if (func261(data[2]) == 0)
+ return 0;
+ if (func262(data[2]) == 0)
+ return 0;
+ if (func263(data[0], data[1]) == 0)
+ return 0;
+ if (func264(data[0], data[1]) == 0)
+ return 0;
+ if (func265(data[0], data[6]) == 0)
+ return 0;
+ if (func266(data[7], data[4]) == 0)
+ return 0;
+ if (func267(data[16], data[7]) == 0)
+ return 0;
+ if (func268(data[0], data[1]) == 0)
+ return 0;
+ if (func269(data[0], data[1]) == 0)
+ return 0;
+ if (func270(data[18], data[1]) == 0)
+ return 0;
+ if (func271(data[13], data[3]) == 0)
+ return 0;
+ if (func272(data[2]) == 0)
+ return 0;
+ if (func273(data[0], data[1]) == 0)
+ return 0;
+ if (func274(data[2]) == 0)
+ return 0;
+ if (func275(data[0], data[1]) == 0)
+ return 0;
+ if (func276(data[14]) == 0)
+ return 0;
+ if (func277(data[0]) == 0)
+ return 0;
+ if (func278(data[19]) == 0)
+ return 0;
+ if (func279(data[0], data[6]) == 0)
+ return 0;
+ if (func280(data[2]) == 0)
+ return 0;
+ if (func281(data[0], data[1]) == 0)
+ return 0;
+ if (func282(data[8], data[0]) == 0)
+ return 0;
+ if (func283(data[14]) == 0)
+ return 0;
+ if (func284(data[19]) == 0)
+ return 0;
+ if (func285(data[14]) == 0)
+ return 0;
+ if (func286(data[19]) == 0)
+ return 0;
+ if (func287(data[11], data[9]) == 0)
+ return 0;
+ if (func288(data[12], data[15]) == 0)
+ return 0;
+ if (func289(data[13], data[1]) == 0)
+ return 0;
+ if (func290(data[7]) == 0)
+ return 0;
+ if (func291(data[13], data[5]) == 0)
+ return 0;
+ if (func292(data[6]) == 0)
+ return 0;
+ if (func293(data[14]) == 0)
+ return 0;
+ if (func294(data[19]) == 0)
+ return 0;
+ if (func295(data[11], data[9]) == 0)
+ return 0;
+ if (func296(data[12], data[15]) == 0)
+ return 0;
+ if (func297(data[12], data[4]) == 0)
+ return 0;
+ if (func298(data[7]) == 0)
+ return 0;
+ if (func299(data[13], data[5]) == 0)
+ return 0;
+ if (func300(data[12], data[14]) == 0)
+ return 0;
+ if (func301(data[6]) == 0)
+ return 0;
+ if (func302(data[14]) == 0)
+ return 0;
+ if (func303(data[19]) == 0)
+ return 0;
+ if (func304(data[11], data[9]) == 0)
+ return 0;
+ if (func305(data[12], data[15]) == 0)
+ return 0;
+ if (func306(data[13], data[1]) == 0)
+ return 0;
+ if (func307(data[6]) == 0)
+ return 0;
+ if (func308(data[19]) == 0)
+ return 0;
+ if (func309(data[12], data[15]) == 0)
+ return 0;
+ if (func310(data[13], data[1]) == 0)
+ return 0;
+ if (func311(data[13], data[5]) == 0)
+ return 0;
+ if (func312(data[6]) == 0)
+ return 0;
+ if (func313(data[14]) == 0)
+ return 0;
+ if (func314(data[0]) == 0)
+ return 0;
+ if (func315(data[9]) == 0)
+ return 0;
+ if (func316(data[11], data[9]) == 0)
+ return 0;
+ if (func317(data[13], data[1]) == 0)
+ return 0;
+ if (func318(data[7]) == 0)
+ return 0;
+ if (func319(data[13], data[4]) == 0)
+ return 0;
+ if (func320(data[16]) == 0)
+ return 0;
+ if (func321(data[4]) == 0)
+ return 0;
+ if (func322(data[0]) == 0)
+ return 0;
+ if (func323(data[19]) == 0)
+ return 0;
+ if (func324(data[11], data[9]) == 0)
+ return 0;
+ if (func325(data[12], data[15]) == 0)
+ return 0;
+ if (func326(data[7]) == 0)
+ return 0;
+ if (func327(data[13], data[5]) == 0)
+ return 0;
+ if (func328(data[0]) == 0)
+ return 0;
+ if (func329(data[19]) == 0)
+ return 0;
+ if (func330(data[11], data[9]) == 0)
+ return 0;
+ if (func331(data[12], data[15]) == 0)
+ return 0;
+ if (func332(data[13], data[1]) == 0)
+ return 0;
+ if (func333(data[4]) == 0)
+ return 0;
+ if (func334(data[13], data[5]) == 0)
+ return 0;
+ if (func335(data[6]) == 0)
+ return 0;
+ if (func336(data[4], data[12]) == 0)
+ return 0;
+ if (func337(data[16]) == 0)
+ return 0;
+ if (func338(data[6]) == 0)
+ return 0;
+ if (func339(data[16]) == 0)
+ return 0;
+ if (func340(data[0]) == 0)
+ return 0;
+ if (func341(data[19]) == 0)
+ return 0;
+ if (func342(data[11], data[9]) == 0)
+ return 0;
+ if (func343(data[12], data[15]) == 0)
+ return 0;
+ if (func344(data[13], data[1]) == 0)
+ return 0;
+ if (func345(data[7]) == 0)
+ return 0;
+ if (func346(data[13], data[5]) == 0)
+ return 0;
+ if (func347(data[6]) == 0)
+ return 0;
+ if (func348(data[4], data[12]) == 0)
+ return 0;
+ if (func349(data[16]) == 0)
+ return 0;
+ if (func350(data[6]) == 0)
+ return 0;
+ if (func351(data[4], data[12]) == 0)
+ return 0;
+ if (func352(data[16]) == 0)
+ return 0;
+ if (func353(data[0]) == 0)
+ return 0;
+ if (func354(data[19]) == 0)
+ return 0;
+ if (func355(data[11], data[9]) == 0)
+ return 0;
+ if (func356(data[8], data[15]) == 0)
+ return 0;
+ if (func357(data[7], data[1]) == 0)
+ return 0;
+ if (func358(data[17]) == 0)
+ return 0;
+ if (func359(data[3], data[5]) == 0)
+ return 0;
+ if (func360(data[6]) == 0)
+ return 0;
+ if (func361(data[4], data[12]) == 0)
+ return 0;
+ if (func362(data[16]) == 0)
+ return 0;
+ if (func363(data[6]) == 0)
+ return 0;
+ if (func364(data[4], data[12]) == 0)
+ return 0;
+ if (func365(data[16]) == 0)
+ return 0;
+ if (func366(data[16]) == 0)
+ return 0;
+ if (func367(data[14]) == 0)
+ return 0;
+ if (func368(data[0]) == 0)
+ return 0;
+ if (func369(data[19]) == 0)
+ return 0;
+ if (func370(data[3], data[1]) == 0)
+ return 0;
+ if (func371(data[4], data[1]) == 0)
+ return 0;
+ if (func372(data[16]) == 0)
+ return 0;
+ if (func373(data[14]) == 0)
+ return 0;
+ if (func374(data[19]) == 0)
+ return 0;
+ if (func375(data[0], data[1]) == 0)
+ return 0;
+ if (func376(data[0], data[1]) == 0)
+ return 0;
+ if (func377(data[2]) == 0)
+ return 0;
+ if (func378(data[0], data[1]) == 0)
+ return 0;
+ if (func379(data[0], data[1]) == 0)
+ return 0;
+ if (func380(data[18], data[1]) == 0)
+ return 0;
+ if (func381(data[0], data[6]) == 0)
+ return 0;
+ if (func382(data[2]) == 0)
+ return 0;
+ if (func383(data[8], data[1]) == 0)
+ return 0;
+ if (func384(data[5], data[1]) == 0)
+ return 0;
+ if (func385(data[18], data[1]) == 0)
+ return 0;
+ if (func386(data[0], data[6]) == 0)
+ return 0;
+ if (func387(data[2]) == 0)
+ return 0;
+ if (func388(data[0], data[1]) == 0)
+ return 0;
+ if (func389(data[18], data[1]) == 0)
+ return 0;
+ if (func390(data[0], data[6]) == 0)
+ return 0;
+ if (func391(data[2]) == 0)
+ return 0;
+ if (func392(data[18], data[1]) == 0)
+ return 0;
+ if (func393(data[0], data[6]) == 0)
+ return 0;
+ if (func394(data[2]) == 0)
+ return 0;
+ if (func395(data[0], data[1]) == 0)
+ return 0;
+ if (func396(data[0], data[1]) == 0)
+ return 0;
+ if (func397(data[18], data[1]) == 0)
+ return 0;
+ if (func398(data[9]) == 0)
+ return 0;
+ if (func399(data[0], data[1]) == 0)
+ return 0;
+ if (func400(data[0], data[1]) == 0)
+ return 0;
+ if (func401(data[8], data[6]) == 0)
+ return 0;
+ if (func402(data[12]) == 0)
+ return 0;
+ if (func403(data[0], data[1]) == 0)
+ return 0;
+ if (func404(data[12]) == 0)
+ return 0;
+ if (func405(data[1]) == 0)
+ return 0;
+ if (func406(data[0], data[6]) == 0)
+ return 0;
+ if (func407(data[4]) == 0)
+ return 0;
+ if (func408(data[0], data[1]) == 0)
+ return 0;
+ if (func409(data[14]) == 0)
+ return 0;
+ if (func410(data[14]) == 0)
+ return 0;
+
+ fprintf(stderr, "BINGO\n");
+ abort();
+ return 1;
+}
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
+ if (api(Data, Size)) {
+ // Should've crashed before getting here.
+ return 0;
+ }
+ return 0;
+}
+
diff --git a/test/fuzzer/NullDerefTest.cpp b/test/fuzzer/NullDerefTest.cpp
index 1b44b682ace6..48df0f54cfe0 100644
--- a/test/fuzzer/NullDerefTest.cpp
+++ b/test/fuzzer/NullDerefTest.cpp
@@ -5,7 +5,7 @@
#include <cstddef>
#include <cstdint>
#include <cstdlib>
-#include <iostream>
+#include <cstdio>
static volatile int Sink;
static volatile int *Null = 0;
@@ -16,7 +16,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
if (Size > 1 && Data[1] == 'i') {
Sink = 2;
if (Size > 2 && Data[2] == '!') {
- std::cout << "Found the target, dereferencing NULL\n";
+ printf("Found the target, dereferencing NULL\n");
*Null = 1;
}
}
diff --git a/test/fuzzer/OnlySomeBytesTest.cpp b/test/fuzzer/OnlySomeBytesTest.cpp
new file mode 100644
index 000000000000..076cda063459
--- /dev/null
+++ b/test/fuzzer/OnlySomeBytesTest.cpp
@@ -0,0 +1,40 @@
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+
+// Find ABCxxFxUxZxxx... (2048+ bytes, 'x' is any byte)
+#include <assert.h>
+#include <cstddef>
+#include <cstdint>
+#include <cstdlib>
+#include <cstring>
+#include <cstdio>
+
+const size_t N = 2048;
+typedef const uint8_t *IN;
+
+static volatile int one = 1;
+
+extern "C" {
+__attribute__((noinline)) void bad() {
+ fprintf(stderr, "BINGO\n");
+ if (one)
+ abort();
+}
+
+__attribute__((noinline)) void f0(IN in) {
+ uint32_t x = in[5] + 251 * in[7] + 251 * 251 * in[9];
+ if (x == 'F' + 251 * 'U' + 251 * 251 * 'Z')
+ bad();
+}
+
+__attribute__((noinline)) void fC(IN in) { if (in[2] == 'C') f0(in); }
+__attribute__((noinline)) void fB(IN in) { if (in[1] == 'B') fC(in); }
+__attribute__((noinline)) void fA(IN in) { if (in[0] == 'A') fB(in); }
+
+} // extern "C"
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
+ if (Size < N) return 0;
+ fA((IN)Data);
+ return 0;
+}
diff --git a/test/fuzzer/PrintUnstableStatsTest.cpp b/test/fuzzer/PrintUnstableStatsTest.cpp
new file mode 100644
index 000000000000..078eb4c3d971
--- /dev/null
+++ b/test/fuzzer/PrintUnstableStatsTest.cpp
@@ -0,0 +1,69 @@
+#include <assert.h>
+#include <cstdint>
+#include <cstdio>
+#include <cstdlib>
+
+int x = 0;
+bool skip0 = false;
+bool skip1 = false;
+bool skip2 = false;
+
+__attribute__((noinline)) void det0() { x++; }
+__attribute__((noinline)) void det1() { x++; }
+__attribute__((noinline)) void det2() { x++; }
+__attribute__((noinline)) void det3() { x++; }
+__attribute__((noinline)) void det4() { x++; }
+
+__attribute__((noinline)) void ini0() { x++; }
+__attribute__((noinline)) void ini1() { x++; }
+__attribute__((noinline)) void ini2() { x++; }
+
+__attribute__((noinline)) void t0() { x++; }
+__attribute__((noinline)) void t1() { x++; }
+__attribute__((noinline)) void t2() { x++; }
+__attribute__((noinline)) void t3() { x++; }
+__attribute__((noinline)) void t4() { x++; }
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
+ if (Size == 1 && Data[0] == 'A' && !skip0) {
+ skip0 = true;
+ ini0();
+ }
+ if (Size == 1 && Data[0] == 'B' && !skip1) {
+ skip1 = true;
+ ini1();
+ }
+ if (Size == 1 && Data[0] == 'C' && !skip2) {
+ skip2 = true;
+ ini2();
+ }
+
+ det0();
+ det1();
+ int a = rand();
+ det2();
+
+ switch (a % 5) {
+ case 0:
+ t0();
+ break;
+ case 1:
+ t1();
+ break;
+ case 2:
+ t2();
+ break;
+ case 3:
+ t3();
+ break;
+ case 4:
+ t4();
+ break;
+ default:
+ assert(false);
+ }
+
+ det3();
+ det4();
+ return 0;
+}
diff --git a/test/fuzzer/ShrinkValueProfileTest.cpp b/test/fuzzer/ShrinkValueProfileTest.cpp
index 86e4e3cb0d9a..dddf493da697 100644
--- a/test/fuzzer/ShrinkValueProfileTest.cpp
+++ b/test/fuzzer/ShrinkValueProfileTest.cpp
@@ -1,7 +1,7 @@
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
-// Test that we can find the minimal item in the corpus (3 bytes: "FUZ").
+// Test that we can find the minimal item in the corpus (4 bytes: "FUZZ").
#include <cstddef>
#include <cstdint>
#include <cstdio>
diff --git a/test/fuzzer/SimpleCmpTest.cpp b/test/fuzzer/SimpleCmpTest.cpp
index 8acad4ac77e8..3bb28c17318b 100644
--- a/test/fuzzer/SimpleCmpTest.cpp
+++ b/test/fuzzer/SimpleCmpTest.cpp
@@ -17,15 +17,15 @@ bool PrintOnce(int Line) {
}
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
- if (Size != 22) return 0;
+ if (Size != 24) return 0;
uint64_t x = 0;
int64_t y = 0;
int32_t z = 0;
- uint16_t a = 0;
+ uint32_t a = 0;
memcpy(&x, Data, 8); // 8
memcpy(&y, Data + 8, 8); // 16
memcpy(&z, Data + 16, sizeof(z)); // 20
- memcpy(&a, Data + 20, sizeof(a)); // 22
+ memcpy(&a, Data + 20, sizeof(a)); // 24
const bool k32bit = sizeof(void*) == 4;
if ((k32bit || x > 1234567890) && PrintOnce(__LINE__) &&
diff --git a/test/fuzzer/SimpleTestStdio.cpp b/test/fuzzer/SimpleTestStdio.cpp
new file mode 100644
index 000000000000..ed7fe1cb3f67
--- /dev/null
+++ b/test/fuzzer/SimpleTestStdio.cpp
@@ -0,0 +1,26 @@
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+
+// Simple test for a fuzzer. The fuzzer must find the string "Hi!".
+#include <assert.h>
+#include <cstdint>
+#include <cstdio>
+#include <cstdlib>
+
+static volatile int Sink;
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
+ assert(Data);
+ if (Size > 0 && Data[0] == 'H') {
+ Sink = 1;
+ if (Size > 1 && Data[1] == 'i') {
+ Sink = 2;
+ if (Size > 2 && Data[2] == '!') {
+ fprintf(stderr, "BINGO; Found the target, exiting\n");
+ exit(0);
+ }
+ }
+ }
+ return 0;
+}
+
diff --git a/test/fuzzer/SwapCmpTest.cpp b/test/fuzzer/SwapCmpTest.cpp
index bbfbefe6ab71..5aa47beb22bb 100644
--- a/test/fuzzer/SwapCmpTest.cpp
+++ b/test/fuzzer/SwapCmpTest.cpp
@@ -11,14 +11,14 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
if (Size < 14) return 0;
uint64_t x = 0;
uint32_t y = 0;
- uint16_t z = 0;
+ uint32_t z = 0;
memcpy(&x, Data, sizeof(x));
memcpy(&y, Data + Size / 2, sizeof(y));
memcpy(&z, Data + Size - sizeof(z), sizeof(z));
x = __builtin_bswap64(x);
y = __builtin_bswap32(y);
- z = __builtin_bswap16(z);
+ z = __builtin_bswap32(z);
const bool k32bit = sizeof(void*) == 4;
if ((k32bit || x == 0x46555A5A5A5A5546ULL) &&
@@ -26,7 +26,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
y == 0x66757A7A &&
true
) {
- if (Data[Size - 3] == 'z') {
+ if (Data[Size - 5] == 'z') {
fprintf(stderr, "BINGO; Found the target\n");
exit(1);
}
diff --git a/test/fuzzer/SymbolizeDeadlock.cpp b/test/fuzzer/SymbolizeDeadlock.cpp
new file mode 100644
index 000000000000..5be1be804bce
--- /dev/null
+++ b/test/fuzzer/SymbolizeDeadlock.cpp
@@ -0,0 +1,35 @@
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+
+// Tests that deadlocks do not occur when an OOM occurs during symbolization.
+
+#include <cassert>
+#include <cstdint>
+#include <cstdio>
+#include <cstdlib>
+#include <cstring>
+#include <unistd.h>
+
+#include "Bingo.h"
+
+volatile unsigned Sink = 0;
+
+// Do not inline this function. We want to trigger NEW_FUNC symbolization when
+// libFuzzer finds this function. We use a macro to make the name as long
+// possible, hoping to increase the time spent in symbolization and increase the
+// chances of triggering a deadlock.
+__attribute__((noinline)) void BINGO() {
+ // Busy work. Inserts a delay here so the deadlock is more likely to trigger.
+ for (unsigned i = 0; i < 330000000; i++) Sink += i;
+}
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
+ assert(Data);
+ if (Size < 3) return 0;
+ if (Data[0] == 'F' &&
+ Data[1] == 'U' &&
+ Data[2] == 'Z')
+ BINGO();
+ return 0;
+}
+
diff --git a/test/fuzzer/ThreadedLeakTest.cpp b/test/fuzzer/ThreadedLeakTest.cpp
index 538d3b434808..59f3671fe9db 100644
--- a/test/fuzzer/ThreadedLeakTest.cpp
+++ b/test/fuzzer/ThreadedLeakTest.cpp
@@ -6,7 +6,7 @@
#include <cstdint>
#include <thread>
-static volatile int *Sink;
+static int * volatile Sink;
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
if (Size == 0) return 0;
diff --git a/test/fuzzer/ThreeBytes.cpp b/test/fuzzer/ThreeBytes.cpp
new file mode 100644
index 000000000000..754a5b0b56a1
--- /dev/null
+++ b/test/fuzzer/ThreeBytes.cpp
@@ -0,0 +1,14 @@
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+
+// Find FUZ
+#include <cstddef>
+#include <cstdint>
+#include <cstdlib>
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
+ if (Size < 3) return 0;
+ uint32_t x = Data[0] + 251 * Data[1] + 251 * 251 * Data[2];
+ if (x == 'F' + 251 * 'U' + 251 * 251 * 'Z') abort();
+ return 0;
+}
diff --git a/test/fuzzer/ThreeFunctionsTest.cpp b/test/fuzzer/ThreeFunctionsTest.cpp
new file mode 100644
index 000000000000..1278cb05633d
--- /dev/null
+++ b/test/fuzzer/ThreeFunctionsTest.cpp
@@ -0,0 +1,36 @@
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+
+// Find "FUZZME", the target has 3 different functions.
+#include <assert.h>
+#include <cstddef>
+#include <cstdint>
+#include <cstdlib>
+#include <cstdio>
+
+extern "C"
+__attribute__((noinline))
+bool Func1(const uint8_t *Data, size_t Size) {
+ // assumes Size >= 5, doesn't check it.
+ return Data[4] == 'M';
+}
+
+extern "C"
+__attribute__((noinline))
+bool Func2(const uint8_t *Data, size_t Size) {
+ return Size >= 6 && Data[5] == 'E';
+}
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
+ if (Size >= 5
+ && Data[0] == 'F'
+ && Data[1] == 'U'
+ && Data[2] == 'Z'
+ && Data[3] == 'Z'
+ && Func1(Data, Size)
+ && Func2(Data, Size)) {
+ fprintf(stderr, "BINGO\n");
+ abort();
+ }
+ return 0;
+}
diff --git a/test/fuzzer/TraceMallocThreadedTest.cpp b/test/fuzzer/TraceMallocThreadedTest.cpp
index 5603af344cb7..0183d939af51 100644
--- a/test/fuzzer/TraceMallocThreadedTest.cpp
+++ b/test/fuzzer/TraceMallocThreadedTest.cpp
@@ -7,11 +7,12 @@
#include <cstddef>
#include <cstdint>
#include <cstring>
+#include <cstdlib>
#include <thread>
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
auto C = [&] {
- volatile void *a = malloc(5639);
+ void * volatile a = malloc(5639);
free((void *)a);
};
std::thread T[] = {std::thread(C), std::thread(C), std::thread(C),
diff --git a/test/fuzzer/UninitializedStrlen.cpp b/test/fuzzer/UninitializedStrlen.cpp
new file mode 100644
index 000000000000..5a4e778df94b
--- /dev/null
+++ b/test/fuzzer/UninitializedStrlen.cpp
@@ -0,0 +1,14 @@
+#include <cstdint>
+#include <cstring>
+
+volatile size_t Sink;
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
+ if (Size < 4) return 0;
+ if (Data[0] == 'F' && Data[1] == 'U' && Data[2] == 'Z' && Data[3] == 'Z') {
+ char uninit[7];
+ Sink = strlen(uninit);
+ }
+ return 0;
+}
+
diff --git a/test/fuzzer/UseAfterDtor.cpp b/test/fuzzer/UseAfterDtor.cpp
new file mode 100644
index 000000000000..dcefca5cc7d5
--- /dev/null
+++ b/test/fuzzer/UseAfterDtor.cpp
@@ -0,0 +1,27 @@
+#include <cstdint>
+#include <cstdio>
+
+struct Simple {
+ int x_;
+ Simple() {
+ x_ = 5;
+ }
+ ~Simple() {
+ x_ += 1;
+ }
+};
+
+Simple *volatile SimpleSink;
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
+ if (Size < 4) return 0;
+ if (Data[0] == 'F' && Data[1] == 'U' && Data[2] == 'Z' && Data[3] == 'Z') {
+ {
+ Simple S;
+ SimpleSink = &S;
+ }
+ if (SimpleSink->x_) fprintf(stderr, "Failed to catch use-after-dtor\n");
+ }
+ return 0;
+}
+
diff --git a/test/fuzzer/acquire-crash-state.test b/test/fuzzer/acquire-crash-state.test
new file mode 100644
index 000000000000..952ec735be6f
--- /dev/null
+++ b/test/fuzzer/acquire-crash-state.test
@@ -0,0 +1,3 @@
+RUN: %cpp_compiler %S/AcquireCrashStateTest.cpp -o %t
+RUN: %run %t 2>&1 | FileCheck %s
+CHECK-NOT: fuzz target exited
diff --git a/test/fuzzer/afl-driver-extra-stats.test b/test/fuzzer/afl-driver-extra-stats.test
index a6de53302002..cddb683e6dec 100644
--- a/test/fuzzer/afl-driver-extra-stats.test
+++ b/test/fuzzer/afl-driver-extra-stats.test
@@ -1,8 +1,9 @@
-RUN: %no_fuzzer_cpp_compiler -fno-sanitize-coverage=edge,trace-cmp,indirect-calls,8bit-counters,trace-pc-guard %S/AFLDriverTest.cpp %libfuzzer_src/afl/afl_driver.cpp -o %t-AFLDriverTest
+XFAIL: ios
+RUN: %no_fuzzer_cpp_compiler %S/AFLDriverTest.cpp %libfuzzer_src/afl/afl_driver.cpp -o %t-AFLDriverTest
; Test that not specifying an extra stats file isn't broken.
RUN: unset AFL_DRIVER_EXTRA_STATS_FILENAME
-RUN: %t-AFLDriverTest
+RUN: %run %t-AFLDriverTest
; Test that specifying an invalid extra stats file causes a crash.
RUN: ASAN_OPTIONS= AFL_DRIVER_EXTRA_STATS_FILENAME=%T not --crash %t-AFLDriverTest
diff --git a/test/fuzzer/afl-driver-stderr.test b/test/fuzzer/afl-driver-stderr.test
index be0efaa8f03e..d3d739d3b977 100644
--- a/test/fuzzer/afl-driver-stderr.test
+++ b/test/fuzzer/afl-driver-stderr.test
@@ -1,12 +1,14 @@
-RUN: %no_fuzzer_cpp_compiler -fno-sanitize-coverage=edge,trace-cmp,indirect-calls,8bit-counters,trace-pc-guard %S/AFLDriverTest.cpp %libfuzzer_src/afl/afl_driver.cpp -o %t-AFLDriverTest
+XFAIL: ios
+UNSUPPORTED: freebsd
+RUN: %no_fuzzer_cpp_compiler %S/AFLDriverTest.cpp %libfuzzer_src/afl/afl_driver.cpp -o %t-AFLDriverTest
; Test that not specifying a stderr file isn't broken.
RUN: unset AFL_DRIVER_STDERR_DUPLICATE_FILENAME
-RUN: %t-AFLDriverTest
+RUN: %run %t-AFLDriverTest
; Test that specifying an invalid file causes a crash.
-RUN: ASAN_OPTIONS= AFL_DRIVER_STDERR_DUPLICATE_FILENAME="%T" not --crash %t-AFLDriverTest
+RUN: ASAN_OPTIONS= AFL_DRIVER_STDERR_DUPLICATE_FILENAME="%T" not --crash %run %t-AFLDriverTest
; Test that a file is created when specified as the duplicate stderr.
-RUN: AFL_DRIVER_STDERR_DUPLICATE_FILENAME=%t %t-AFLDriverTest
+RUN: AFL_DRIVER_STDERR_DUPLICATE_FILENAME=%t %run %t-AFLDriverTest
RUN: stat %t
diff --git a/test/fuzzer/afl-driver.test b/test/fuzzer/afl-driver.test
index 32e7d03b43c0..552bafb0bf34 100644
--- a/test/fuzzer/afl-driver.test
+++ b/test/fuzzer/afl-driver.test
@@ -1,29 +1,29 @@
REQUIRES: linux
-RUN: %no_fuzzer_cpp_compiler -fno-sanitize-coverage=edge,trace-cmp,indirect-calls,8bit-counters,trace-pc-guard %S/AFLDriverTest.cpp %libfuzzer_src/afl/afl_driver.cpp -o %t-AFLDriverTest
+RUN: %no_fuzzer_cpp_compiler %S/AFLDriverTest.cpp %libfuzzer_src/afl/afl_driver.cpp -o %t-AFLDriverTest
RUN: echo -n "abc" > %t.file3
RUN: echo -n "abcd" > %t.file4
-RUN: %t-AFLDriverTest < %t.file3 2>&1 | FileCheck %s --check-prefix=CHECK1
+RUN: %run %t-AFLDriverTest < %t.file3 2>&1 | FileCheck %s --check-prefix=CHECK1
CHECK1: __afl_persistent_loop calle, Count = 1000
CHECK1: LLVMFuzzerTestOneInput called; Size = 3
-RUN: %t-AFLDriverTest < %t.file3 -42 2>&1 | FileCheck %s --check-prefix=CHECK2
+RUN: %run %t-AFLDriverTest < %t.file3 -42 2>&1 | FileCheck %s --check-prefix=CHECK2
CHECK2: __afl_persistent_loop calle, Count = 42
CHECK2: LLVMFuzzerTestOneInput called; Size = 3
-RUN: %t-AFLDriverTest < %t.file3 666 2>&1 | FileCheck %s --check-prefix=CHECK3
+RUN: %run %t-AFLDriverTest < %t.file3 666 2>&1 | FileCheck %s --check-prefix=CHECK3
CHECK3: WARNING: using the deprecated call style
CHECK3: __afl_persistent_loop calle, Count = 666
CHECK3: LLVMFuzzerTestOneInput called; Size = 3
-RUN: %t-AFLDriverTest %t.file3 2>&1 | FileCheck %s --check-prefix=CHECK4
+RUN: %run %t-AFLDriverTest %t.file3 2>&1 | FileCheck %s --check-prefix=CHECK4
CHECK4: LLVMFuzzerTestOneInput called; Size = 3
-RUN: %t-AFLDriverTest %t.file3 %t.file4 2>&1 | FileCheck %s --check-prefix=CHECK5
+RUN: %run %t-AFLDriverTest %t.file3 %t.file4 2>&1 | FileCheck %s --check-prefix=CHECK5
CHECK5: LLVMFuzzerTestOneInput called; Size = 3
CHECK5: LLVMFuzzerTestOneInput called; Size = 4
diff --git a/test/fuzzer/bad-strcmp.test b/test/fuzzer/bad-strcmp.test
index fd1621a4e1eb..7fb2a6f07353 100644
--- a/test/fuzzer/bad-strcmp.test
+++ b/test/fuzzer/bad-strcmp.test
@@ -1,2 +1,2 @@
RUN: %cpp_compiler %S/BadStrcmpTest.cpp -o %t-BadStrcmpTest
-RUN: %t-BadStrcmpTest -runs=100000
+RUN: %run %t-BadStrcmpTest -runs=100000
diff --git a/test/fuzzer/bogus-initialize.test b/test/fuzzer/bogus-initialize.test
new file mode 100644
index 000000000000..2dff2d5a2639
--- /dev/null
+++ b/test/fuzzer/bogus-initialize.test
@@ -0,0 +1,4 @@
+RUN: %cpp_compiler %S/BogusInitializeTest.cpp -o %t-BogusInitializeTest
+
+RUN: not %run %t-BogusInitializeTest 2>&1 | FileCheck %s --check-prefix=BOGUS_INITIALIZE
+BOGUS_INITIALIZE: argv[0] has been modified in LLVMFuzzerInitialize
diff --git a/test/fuzzer/buffer-overflow-on-input.test b/test/fuzzer/buffer-overflow-on-input.test
new file mode 100644
index 000000000000..6e40b75d70bc
--- /dev/null
+++ b/test/fuzzer/buffer-overflow-on-input.test
@@ -0,0 +1,5 @@
+RUN: %cpp_compiler %S/BufferOverflowOnInput.cpp -o %t-BufferOverflowOnInput
+
+RUN: not %run %t-BufferOverflowOnInput 2>&1 | FileCheck %s --check-prefix=OOB
+OOB: AddressSanitizer: heap-buffer-overflow
+OOB: is located 0 bytes to the right of 3-byte region
diff --git a/test/fuzzer/caller-callee.test b/test/fuzzer/caller-callee.test
index e4eccdc307ad..679e4a6f65a4 100644
--- a/test/fuzzer/caller-callee.test
+++ b/test/fuzzer/caller-callee.test
@@ -1,3 +1,4 @@
+UNSUPPORTED: freebsd
RUN: %cpp_compiler %S/CallerCalleeTest.cpp -o %t-CallerCalleeTest
CHECK: BINGO
-RUN: not %t-CallerCalleeTest -use_value_profile=1 -cross_over=0 -seed=1 -runs=10000000 2>&1 | FileCheck %s
+RUN: not %run %t-CallerCalleeTest -use_value_profile=1 -cross_over=0 -seed=1 -runs=10000000 2>&1 | FileCheck %s
diff --git a/test/fuzzer/cleanse.test b/test/fuzzer/cleanse.test
index 8e45dc77d9ea..3447fcf0ff26 100644
--- a/test/fuzzer/cleanse.test
+++ b/test/fuzzer/cleanse.test
@@ -1,4 +1,4 @@
RUN: %cpp_compiler %S/CleanseTest.cpp -o %t-CleanseTest
RUN: echo -n 0123456789ABCDEFGHIZ > %t-in
-RUN: %t-CleanseTest -cleanse_crash=1 %t-in -exact_artifact_path=%t-out
+RUN: %run %t-CleanseTest -cleanse_crash=1 %t-in -exact_artifact_path=%t-out
RUN: echo -n ' 1 5 A Z' | diff - %t-out
diff --git a/test/fuzzer/counters.test b/test/fuzzer/counters.test
new file mode 100644
index 000000000000..f75d3a03783f
--- /dev/null
+++ b/test/fuzzer/counters.test
@@ -0,0 +1,9 @@
+XFAIL: ios
+UNSUPPORTED: aarch64
+RUN: %cpp_compiler %S/CounterTest.cpp -o %t-CounterTest
+RUN: not %run %t-CounterTest -max_len=6 -seed=1 -timeout=15 2>&1 | FileCheck %s --check-prefix=COUNTERS
+
+COUNTERS: INITED {{.*}} {{bits:|ft:}}
+COUNTERS: NEW {{.*}} {{bits:|ft:}} {{[1-9]*}}
+COUNTERS: NEW {{.*}} {{bits:|ft:}} {{[1-9]*}}
+COUNTERS: BINGO
diff --git a/test/fuzzer/coverage.test b/test/fuzzer/coverage.test
index 9a2179d91add..3b2341f21f69 100644
--- a/test/fuzzer/coverage.test
+++ b/test/fuzzer/coverage.test
@@ -1,21 +1,18 @@
+UNSUPPORTED: aarch64
RUN: %cpp_compiler -mllvm -use-unknown-locations=Disable %S/NullDerefTest.cpp -o %t-NullDerefTest
-RUN: %cpp_compiler -mllvm -use-unknown-locations=Disable %S/DSO1.cpp -fPIC -shared -o %t-DSO1.so
-RUN: %cpp_compiler -mllvm -use-unknown-locations=Disable %S/DSO2.cpp -fPIC -shared -o %t-DSO2.so
-RUN: %cpp_compiler -mllvm -use-unknown-locations=Disable %S/DSOTestMain.cpp %S/DSOTestExtra.cpp -L. %t-DSO1.so %t-DSO2.so -o %t-DSOTest
+RUN: %cpp_compiler -mllvm -use-unknown-locations=Disable %S/DSO1.cpp -fPIC %ld_flags_rpath_so1 -shared -o %dynamiclib1
+RUN: %cpp_compiler -mllvm -use-unknown-locations=Disable %S/DSO2.cpp -fPIC %ld_flags_rpath_so2 -shared -o %dynamiclib2
+RUN: %cpp_compiler -mllvm -use-unknown-locations=Disable %S/DSOTestMain.cpp %S/DSOTestExtra.cpp %ld_flags_rpath_exe1 %ld_flags_rpath_exe2 -o %t-DSOTest
CHECK: COVERAGE:
-CHECK-DAG: COVERED: {{.*}}in LLVMFuzzerTestOneInput {{.*}}NullDerefTest.cpp:13
-CHECK-DAG: COVERED: {{.*}}in LLVMFuzzerTestOneInput {{.*}}NullDerefTest.cpp:14
-CHECK-DAG: COVERED: {{.*}}in LLVMFuzzerTestOneInput {{.*}}NullDerefTest.cpp:16
-RUN: not %t-NullDerefTest -print_coverage=1 2>&1 | FileCheck %s
+CHECK: COVERED_FUNC: {{.*}}LLVMFuzzerTestOneInput {{.*}}NullDerefTest.cpp:13
+RUN: not %run %t-NullDerefTest -print_coverage=1 2>&1 | FileCheck %s
-RUN: %t-DSOTest -print_coverage=1 -runs=0 2>&1 | FileCheck %s --check-prefix=DSO
+RUN: %run %t-DSOTest -print_coverage=1 -runs=0 2>&1 | FileCheck %s --check-prefix=DSO
DSO: COVERAGE:
-DSO-DAG: COVERED:{{.*}}DSO1{{.*}}DSO1.cpp
-DSO-DAG: COVERED:{{.*}}DSO2{{.*}}DSO2.cpp
-DSO-DAG: COVERED:{{.*}}LLVMFuzzerTestOneInput{{.*}}DSOTestMain
-DSO-DAG: UNCOVERED_LINE:{{.*}}DSO1{{.*}}DSO1.cpp
-DSO-DAG: UNCOVERED_LINE:{{.*}}DSO2{{.*}}DSO2.cpp
-DSO-DAG: UNCOVERED_FUNC: in Uncovered1
-DSO-DAG: UNCOVERED_FUNC: in Uncovered2
-DSO-DAG: UNCOVERED_LINE: in LLVMFuzzerTestOneInput
+DSO-DAG: COVERED_FUNC:{{.*}}1{{.*}}
+DSO-DAG: COVERED_FUNC:{{.*}}2{{.*}}
+DSO-DAG: COVERED_FUNC:{{.*}}LLVMFuzzerTestOneInput{{.*}}DSOTestMain
+DSO-DAG: UNCOVERED_PC:{{.*}}1
+DSO-DAG: UNCOVERED_PC:{{.*}}2
+DSO-DAG: UNCOVERED_PC:{{.*}}DSOTestMain
diff --git a/test/fuzzer/cxxstring.test b/test/fuzzer/cxxstring.test
index 7bb341ba22b4..65edeec1964a 100644
--- a/test/fuzzer/cxxstring.test
+++ b/test/fuzzer/cxxstring.test
@@ -1,6 +1,6 @@
-UNSUPPORTED: windows
+UNSUPPORTED: windows,freebsd
RUN: %cpp_compiler %S/CxxStringEqTest.cpp -o %t-CxxStringEqTest
-RUN: not %t-CxxStringEqTest -seed=1 -runs=1000000 2>&1 | FileCheck %s
+RUN: not %run %t-CxxStringEqTest -seed=1 -runs=1000000 2>&1 | FileCheck %s
CHECK: BINGO
diff --git a/test/fuzzer/dataflow.test b/test/fuzzer/dataflow.test
new file mode 100644
index 000000000000..64f083735cb9
--- /dev/null
+++ b/test/fuzzer/dataflow.test
@@ -0,0 +1,84 @@
+# Tests the data flow tracer.
+REQUIRES: linux
+UNSUPPORTED: aarch64
+
+# Build the tracer and the test.
+RUN: %no_fuzzer_cpp_compiler -c -fno-sanitize=all -fsanitize=dataflow %S/../../lib/fuzzer/dataflow/DataFlow.cpp -o %t-DataFlow.o
+RUN: %no_fuzzer_cpp_compiler -fno-sanitize=all -fsanitize=dataflow -fsanitize-coverage=trace-pc-guard,pc-table,func,trace-cmp %S/ThreeFunctionsTest.cpp %t-DataFlow.o -o %t-ThreeFunctionsTestDF
+RUN: %no_fuzzer_cpp_compiler -fno-sanitize=all -fsanitize=dataflow -fsanitize-coverage=trace-pc-guard,pc-table,func,trace-cmp %S/ExplodeDFSanLabelsTest.cpp %t-DataFlow.o -o %t-ExplodeDFSanLabelsTestDF
+RUN: %cpp_compiler %S/ThreeFunctionsTest.cpp -o %t-ThreeFunctionsTest
+
+# Dump the function list.
+RUN: %t-ThreeFunctionsTestDF 2>&1 | FileCheck %s --check-prefix=FUNC_LIST
+FUNC_LIST-DAG: LLVMFuzzerTestOneInput
+FUNC_LIST-DAG: Func1
+FUNC_LIST-DAG: Func2
+
+# Prepare the inputs.
+RUN: rm -rf %t/IN
+RUN: mkdir -p %t/IN
+RUN: echo -n ABC > %t/IN/ABC
+RUN: echo -n FUABC > %t/IN/FUABC
+RUN: echo -n FUZZR > %t/IN/FUZZR
+RUN: echo -n FUZZM > %t/IN/FUZZM
+RUN: echo -n FUZZMU > %t/IN/FUZZMU
+RUN: echo -n 1234567890123456 > %t/IN/1234567890123456
+
+# ABC: No data is used, the only used label is 4 (corresponds to the size)
+RUN:%t-ThreeFunctionsTestDF 0 3 %t/IN/ABC | FileCheck %s --check-prefix=IN_ABC
+IN_ABC: F{{[012]}} 0001
+IN_ABC-NOT: F
+
+# FUABC: First 3 bytes are checked, Func1/Func2 are not called.
+RUN:%t-ThreeFunctionsTestDF 0 5 %t/IN/FUABC | FileCheck %s --check-prefix=IN_FUABC
+IN_FUABC: F{{[012]}} 111001
+IN_FUABC-NOT: F
+
+# FUZZR: 5 bytes are used (4 in one function, 5-th in the other), Func2 is not called.
+RUN:%t-ThreeFunctionsTestDF 0 5 %t/IN/FUZZR | FileCheck %s --check-prefix=IN_FUZZR
+IN_FUZZR-DAG: F{{[012]}} 111101
+IN_FUZZR-DAG: F{{[012]}} 000010
+IN_FUZZR-NOT: F
+
+# FUZZM: 5 bytes are used, both Func1 and Func2 are called, Func2 depends only on size (label 6).
+RUN:%t-ThreeFunctionsTestDF 0 5 %t/IN/FUZZM | FileCheck %s --check-prefix=IN_FUZZM
+IN_FUZZM-DAG: F{{[012]}} 000010
+IN_FUZZM-DAG: F{{[012]}} 111101
+IN_FUZZM-DAG: F{{[012]}} 000001
+
+# FUZZMU: 6 bytes are used, both Func1 and Func2 are called, Func2 depends on byte 6 and size (label 7)
+RUN:%t-ThreeFunctionsTestDF 0 6 %t/IN/FUZZMU | FileCheck %s --check-prefix=IN_FUZZMU
+
+# Test merge_data_flow
+RUN:rm -f %t-merge-*
+RUN:%t-ThreeFunctionsTestDF 0 2 %t/IN/FUZZMU > %t-merge-1
+RUN:%t-ThreeFunctionsTestDF 2 4 %t/IN/FUZZMU > %t-merge-2
+RUN:%t-ThreeFunctionsTestDF 4 6 %t/IN/FUZZMU > %t-merge-3
+RUN:%libfuzzer_src/scripts/merge_data_flow.py %t-merge-* | FileCheck %s --check-prefix=IN_FUZZMU
+
+# Test collect_data_flow
+RUN: %libfuzzer_src/scripts/collect_data_flow.py %t-ThreeFunctionsTestDF %t/IN/FUZZMU | FileCheck %s --check-prefix=IN_FUZZMU
+
+IN_FUZZMU-DAG: F{{[012]}} 0000100
+IN_FUZZMU-DAG: F{{[012]}} 1111001
+IN_FUZZMU-DAG: F{{[012]}} 0000011
+
+# A very simple test will cause DFSan to die with "out of labels"
+RUN: not %t-ExplodeDFSanLabelsTestDF 0 16 %t/IN/1234567890123456 2>&1 | FileCheck %s --check-prefix=OUT_OF_LABELS
+OUT_OF_LABELS: ==FATAL: DataFlowSanitizer: out of labels
+# However we can run the same test piece by piece.
+RUN: %t-ExplodeDFSanLabelsTestDF 0 2 %t/IN/1234567890123456
+RUN: %t-ExplodeDFSanLabelsTestDF 2 4 %t/IN/1234567890123456
+RUN: %t-ExplodeDFSanLabelsTestDF 4 6 %t/IN/1234567890123456
+# Or we can use collect_data_flow
+RUN: %libfuzzer_src/scripts/collect_data_flow.py %t-ExplodeDFSanLabelsTestDF %t/IN/1234567890123456
+
+# Test that we can run collect_data_flow on the entire corpus dir
+RUN: rm -rf %t/OUT
+RUN: %libfuzzer_src/scripts/collect_data_flow.py %t-ThreeFunctionsTestDF %t/IN %t/OUT
+RUN: %t-ThreeFunctionsTest -data_flow_trace=%t/OUT -runs=0 -focus_function=Func2 2>&1 | FileCheck %s --check-prefix=USE_DATA_FLOW_TRACE
+USE_DATA_FLOW_TRACE: INFO: Focus function is set to 'Func2'
+USE_DATA_FLOW_TRACE: INFO: DataFlowTrace: reading from {{.*}}/OUT
+USE_DATA_FLOW_TRACE-DAG: a8eefe2fd5d6b32028f355fafa3e739a6bf5edc => |000001|
+USE_DATA_FLOW_TRACE-DGA: d28cb407e8e1a702c72d25473f0553d3ec172262 => |0000011|
+USE_DATA_FLOW_TRACE: INFO: DataFlowTrace: 6 trace files, 3 functions, 2 traces with focus function
diff --git a/test/fuzzer/deep-recursion.test b/test/fuzzer/deep-recursion.test
index 22475f91263a..f65104004bf9 100644
--- a/test/fuzzer/deep-recursion.test
+++ b/test/fuzzer/deep-recursion.test
@@ -1,5 +1,5 @@
# Test that we can find a stack overflow
REQUIRES: linux
RUN: %cpp_compiler %S/DeepRecursionTest.cpp -o %t
-RUN: not %t -seed=1 -runs=100000000 2>&1 | FileCheck %s
+RUN: not %run %t -seed=1 -runs=100000000 2>&1 | FileCheck %s
CHECK: ERROR: libFuzzer: deadly signal
diff --git a/test/fuzzer/disable-leaks.test b/test/fuzzer/disable-leaks.test
index bc120d98b38a..1c65884e3213 100644
--- a/test/fuzzer/disable-leaks.test
+++ b/test/fuzzer/disable-leaks.test
@@ -1,5 +1,6 @@
REQUIRES: lsan
+UNSUPPORTED: aarch64
RUN: %cpp_compiler %S/AccumulateAllocationsTest.cpp -o %t-AccumulateAllocationsTest
-RUN: %t-AccumulateAllocationsTest -detect_leaks=1 -runs=100000 2>&1 | FileCheck %s --check-prefix=ACCUMULATE_ALLOCS
+RUN: %run %t-AccumulateAllocationsTest -detect_leaks=1 -runs=100000 2>&1 | FileCheck %s --check-prefix=ACCUMULATE_ALLOCS
ACCUMULATE_ALLOCS: INFO: libFuzzer disabled leak detection after every mutation
diff --git a/test/fuzzer/dso.test b/test/fuzzer/dso.test
new file mode 100644
index 000000000000..fc1fe23818f0
--- /dev/null
+++ b/test/fuzzer/dso.test
@@ -0,0 +1,7 @@
+RUN: %cpp_compiler %S/DSO1.cpp -fPIC %ld_flags_rpath_so1 -shared -o %dynamiclib1
+RUN: %cpp_compiler %S/DSO2.cpp -fPIC %ld_flags_rpath_so2 -shared -o %dynamiclib2
+RUN: %cpp_compiler %S/DSOTestMain.cpp %S/DSOTestExtra.cpp %ld_flags_rpath_exe1 %ld_flags_rpath_exe2 -o %t-DSOTest
+
+RUN: not %run %t-DSOTest 2>&1 | FileCheck %s --check-prefix=DSO
+DSO: INFO: Loaded 3 modules
+DSO: BINGO
diff --git a/test/fuzzer/dump_coverage.test b/test/fuzzer/dump_coverage.test
index b240089ce239..41e193824de6 100644
--- a/test/fuzzer/dump_coverage.test
+++ b/test/fuzzer/dump_coverage.test
@@ -1,20 +1,21 @@
-RUN: %cpp_compiler -fsanitize-coverage=0 -fsanitize-coverage=trace-pc-guard %S/DSO1.cpp -fPIC -shared -o %t-DSO1.so
-RUN: %cpp_compiler -fsanitize-coverage=0 -fsanitize-coverage=trace-pc-guard %S/DSO2.cpp -fPIC -shared -o %t-DSO2.so
-RUN: %cpp_compiler -fsanitize-coverage=0 -fsanitize-coverage=trace-pc-guard %S/DSOTestMain.cpp %S/DSOTestExtra.cpp -L. %t-DSO1.so %t-DSO2.so -o %t-DSOTest
+UNSUPPORTED: freebsd
+RUN: %cpp_compiler -fsanitize-coverage=0 -fsanitize-coverage=trace-pc-guard %S/DSO1.cpp -fPIC -shared -o %dynamiclib1 %ld_flags_rpath_so1
+RUN: %cpp_compiler -fsanitize-coverage=0 -fsanitize-coverage=trace-pc-guard %S/DSO2.cpp -fPIC -shared -o %dynamiclib2 %ld_flags_rpath_so2
+RUN: %cpp_compiler -fsanitize-coverage=0 -fsanitize-coverage=trace-pc-guard %S/DSOTestMain.cpp %S/DSOTestExtra.cpp %ld_flags_rpath_exe1 %ld_flags_rpath_exe2 -o %t-DSOTest
RUN: %cpp_compiler -fsanitize-coverage=0 -fsanitize-coverage=trace-pc-guard %S/NullDerefTest.cpp -o %t-NullDerefTest
RUN: rm -rf %t_workdir && mkdir -p %t_workdir
-RUN: env ASAN_OPTIONS=coverage_dir='"%t_workdir"' not %t-NullDerefTest -dump_coverage=1 2>&1 | FileCheck %s
+RUN: env ASAN_OPTIONS=coverage_dir='"%t_workdir"' not %run %t-NullDerefTest -dump_coverage=1 2>&1 | FileCheck %s
RUN: sancov -covered-functions %t-NullDerefTest* %t_workdir/*.sancov | FileCheck %s --check-prefix=SANCOV
-RUN: env ASAN_OPTIONS=coverage_dir='"%t_workdir"' %t-DSOTest -dump_coverage=1 -runs=0 2>&1 | FileCheck %s --check-prefix=DSO
-RUN: env ASAN_OPTIONS=coverage_dir='"%t_workdir"' not %t-NullDerefTest -dump_coverage=0 2>&1 | FileCheck %s --check-prefix=NOCOV
+RUN: env ASAN_OPTIONS=coverage_dir='"%t_workdir"' %run %t-DSOTest -dump_coverage=1 -runs=0 2>&1 | FileCheck -allow-deprecated-dag-overlap %s --check-prefix=DSO
+RUN: env ASAN_OPTIONS=coverage_dir='"%t_workdir"' not %run %t-NullDerefTest -dump_coverage=0 2>&1 | FileCheck %s --check-prefix=NOCOV
CHECK: SanitizerCoverage: {{.*}}NullDerefTest.{{.*}}.sancov: {{.*}} PCs written
SANCOV: LLVMFuzzerTestOneInput
DSO: SanitizerCoverage: {{.*}}DSOTest.{{.*}}.sancov: {{.*}} PCs written
-DSO-DAG: SanitizerCoverage: {{.*}}DSO1.{{.*}}.sancov: {{.*}} PCs written
-DSO-DAG: SanitizerCoverage: {{.*}}DSO2.{{.*}}.sancov: {{.*}} PCs written
+DSO-DAG: SanitizerCoverage: {{.*}}.{{.*}}.sancov: {{.*}} PCs written
+DSO-DAG: SanitizerCoverage: {{.*}}2.{{.*}}.sancov: {{.*}} PCs written
NOCOV-NOT: SanitizerCoverage: {{.*}} PCs written
diff --git a/test/fuzzer/equivalence-signals.test b/test/fuzzer/equivalence-signals.test
index 7951636e85f8..1da66f1474f1 100644
--- a/test/fuzzer/equivalence-signals.test
+++ b/test/fuzzer/equivalence-signals.test
@@ -1,9 +1,14 @@
+REQUIRES: this-test-is-deprecated
# Run EquivalenceATest against itself with a small timeout
# to stress the signal handling and ensure that shmem doesn't mind
# the signals.
+UNSUPPORTED: freebsd
+
+# The test is not supported on Darwin
+UNSUPPORTED: darwin
RUN: %cpp_compiler %S/EquivalenceATest.cpp -o %t-EquivalenceATest
-RUN: %t-EquivalenceATest -timeout=1 -run_equivalence_server=EQUIV_SIG_TEST & export APID=$!
+RUN: %run %t-EquivalenceATest -timeout=1 -run_equivalence_server=EQ_SIG_TEST & export APID=$!
RUN: sleep 3
-RUN: %t-EquivalenceATest -timeout=1 -use_equivalence_server=EQUIV_SIG_TEST -runs=500000 2>&1
+RUN: %run %t-EquivalenceATest -timeout=1 -use_equivalence_server=EQ_SIG_TEST -runs=500000 2>&1
RUN: kill -9 $APID
diff --git a/test/fuzzer/equivalence.test b/test/fuzzer/equivalence.test
index 12964f478a45..2438811f2809 100644
--- a/test/fuzzer/equivalence.test
+++ b/test/fuzzer/equivalence.test
@@ -1,9 +1,11 @@
+REQUIRES: this-test-is-deprecated
+UNSUPPORTED: freebsd
RUN: %cpp_compiler %S/EquivalenceATest.cpp -o %t-EquivalenceATest
RUN: %cpp_compiler %S/EquivalenceBTest.cpp -o %t-EquivalenceBTest
-RUN: %t-EquivalenceATest -run_equivalence_server=EQUIV_TEST & export APID=$!
+RUN: %run %t-EquivalenceATest -run_equivalence_server=EQUIV_TEST & export APID=$!
RUN: sleep 3
-RUN: not %t-EquivalenceBTest -use_equivalence_server=EQUIV_TEST -max_len=4096 2>&1 | FileCheck %s
+RUN: not %run %t-EquivalenceBTest -use_equivalence_server=EQUIV_TEST -max_len=4096 2>&1 | FileCheck %s
CHECK: ERROR: libFuzzer: equivalence-mismatch. Sizes: {{.*}}; offset 2
CHECK: SUMMARY: libFuzzer: equivalence-mismatch
RUN: kill -9 $APID
diff --git a/test/fuzzer/exit-report.test b/test/fuzzer/exit-report.test
index f754c1376c43..65d91c5cd88a 100644
--- a/test/fuzzer/exit-report.test
+++ b/test/fuzzer/exit-report.test
@@ -1,5 +1,5 @@
RUN: %cpp_compiler %S/SimpleTest.cpp -o %t-SimpleTest
-RUN: not %t-SimpleTest 2>&1 | FileCheck %s
+RUN: not %run %t-SimpleTest 2>&1 | FileCheck %s
CHECK: ERROR: libFuzzer: fuzz target exited
CHECK: SUMMARY: libFuzzer: fuzz target exited
diff --git a/test/fuzzer/exit_on_src_pos.test b/test/fuzzer/exit_on_src_pos.test
index 6a42c7ae9539..ad0fa0a7ce4e 100644
--- a/test/fuzzer/exit_on_src_pos.test
+++ b/test/fuzzer/exit_on_src_pos.test
@@ -1,8 +1,9 @@
# Temporary use -mllvm -use-unknown-locations=Disable so that
# all instructions have debug info (file line numbers) attached.
-RUN: %cpp_compiler %S/SimpleTest.cpp -o %t-SimpleTest -mllvm -use-unknown-locations=Disable
-RUN: %cpp_compiler %S/ShrinkControlFlowTest.cpp -o %t-ShrinkControlFlowTest
+# TODO: Find out why test fails on Darwin with -O2.
+RUN: %cpp_compiler -O0 %S/SimpleTest.cpp -o %t-SimpleTest -mllvm -use-unknown-locations=Disable
+RUN: %cpp_compiler -O0 %S/ShrinkControlFlowTest.cpp -o %t-ShrinkControlFlowTest
-RUN: %t-SimpleTest -exit_on_src_pos=SimpleTest.cpp:18 2>&1 | FileCheck %s --check-prefix=EXIT_ON_SRC_POS
-RUN: %t-ShrinkControlFlowTest -exit_on_src_pos=Foo 2>&1 | FileCheck %s --check-prefix=EXIT_ON_SRC_POS
+RUN: %run %t-SimpleTest -exit_on_src_pos=SimpleTest.cpp:18 2>&1 | FileCheck %s --check-prefix=EXIT_ON_SRC_POS
+RUN: %run %t-ShrinkControlFlowTest -exit_on_src_pos=Foo 2>&1 | FileCheck %s --check-prefix=EXIT_ON_SRC_POS
EXIT_ON_SRC_POS: INFO: found line matching '{{.*}}', exiting.
diff --git a/test/fuzzer/extra-counters.test b/test/fuzzer/extra-counters.test
index 230f74a1b0bb..a93f775dcfc5 100644
--- a/test/fuzzer/extra-counters.test
+++ b/test/fuzzer/extra-counters.test
@@ -1,7 +1,7 @@
REQUIRES: linux
RUN: %cpp_compiler %S/TableLookupTest.cpp -o %t-TableLookupTest
-RUN: not %t-TableLookupTest -print_final_stats=1 2>&1 | FileCheck %s
-CHECK: BINGO
+RUN: not %run %t-TableLookupTest -print_final_stats=1 2>&1 | FileCheck %s
+CHECK: INFO: {{[0-9]+}} Extra Counters
// Expecting >= 4096 new_units_added
CHECK: stat::new_units_added:{{.*[4][0-9][0-9][0-9]}}
diff --git a/test/fuzzer/fprofile-instr-generate.test b/test/fuzzer/fprofile-instr-generate.test
deleted file mode 100644
index 2a3ec96f10f7..000000000000
--- a/test/fuzzer/fprofile-instr-generate.test
+++ /dev/null
@@ -1,7 +0,0 @@
-# Test libFuzzer + -fprofile-instr-generate
-REQUIRES: linux
-RUN: %cpp_compiler %S/SimpleTest.cpp -fsanitize-coverage=0 -fprofile-instr-generate -o %t-SimpleTest-fprofile-instr-generate
-CHECK-NOT: INFO: Loaded 1 modules
-CHECK: INFO: {{.*}} Clang Coverage Counters
-CHECK: BINGO
-RUN: not %t-SimpleTest-fprofile-instr-generate -runs=1000000 -seed=1 -use_clang_coverage=1 2>&1 | FileCheck %s
diff --git a/test/fuzzer/full-coverage-set.test b/test/fuzzer/full-coverage-set.test
new file mode 100644
index 000000000000..629873d4eb39
--- /dev/null
+++ b/test/fuzzer/full-coverage-set.test
@@ -0,0 +1,3 @@
+CHECK: BINGO
+RUN: %cpp_compiler %S/FullCoverageSetTest.cpp -o %t-FullCoverageSetTest
+#not %run %t-FullCoverageSetTest -timeout=15 -seed=1 -mutate_depth=2 -use_full_coverage_set=1 2>&1 | FileCheck %s
diff --git a/test/fuzzer/fuzzer-customcrossover.test b/test/fuzzer/fuzzer-customcrossover.test
index 5a78307c7a3b..0835081f289a 100644
--- a/test/fuzzer/fuzzer-customcrossover.test
+++ b/test/fuzzer/fuzzer-customcrossover.test
@@ -1,8 +1,8 @@
RUN: %cpp_compiler %S/CustomCrossOverTest.cpp -o %t-CustomCrossOverTest
-RUN: not %t-CustomCrossOverTest -seed=1 -runs=1000000 2>&1 | FileCheck %s --check-prefix=CHECK_CO
+RUN: not %run %t-CustomCrossOverTest -seed=1 -runs=1000000 2>&1 | FileCheck %s --check-prefix=CHECK_CO
Disable cross_over, verify that we can't find the target w/o it.
-RUN: %t-CustomCrossOverTest -seed=1 -runs=1000000 -cross_over=0 2>&1 | FileCheck %s --check-prefix=CHECK_NO_CO
+RUN: %run %t-CustomCrossOverTest -seed=1 -runs=1000000 -cross_over=0 2>&1 | FileCheck %s --check-prefix=CHECK_NO_CO
CHECK_CO: In LLVMFuzzerCustomCrossover
CHECK_CO: BINGO
diff --git a/test/fuzzer/fuzzer-customcrossoverandmutate.test b/test/fuzzer/fuzzer-customcrossoverandmutate.test
index 4a7dfba2ab8b..e538d866ff2d 100644
--- a/test/fuzzer/fuzzer-customcrossoverandmutate.test
+++ b/test/fuzzer/fuzzer-customcrossoverandmutate.test
@@ -1,2 +1,2 @@
RUN: %cpp_compiler %S/CustomCrossOverAndMutateTest.cpp -o %t-CustomCrossOverAndMutateTest
-RUN: %t-CustomCrossOverAndMutateTest -seed=1 -runs=100000
+RUN: %run %t-CustomCrossOverAndMutateTest -seed=1 -runs=100000
diff --git a/test/fuzzer/fuzzer-custommutator.test b/test/fuzzer/fuzzer-custommutator.test
index 7a693cd47324..51aef2373cca 100644
--- a/test/fuzzer/fuzzer-custommutator.test
+++ b/test/fuzzer/fuzzer-custommutator.test
@@ -1,5 +1,5 @@
RUN: %cpp_compiler %S/CustomMutatorTest.cpp -o %t-CustomMutatorTest
-RUN: not %t-CustomMutatorTest 2>&1 | FileCheck %s --check-prefix=LLVMFuzzerCustomMutator
+RUN: not %run %t-CustomMutatorTest 2>&1 | FileCheck %s --check-prefix=LLVMFuzzerCustomMutator
LLVMFuzzerCustomMutator: In LLVMFuzzerCustomMutator
LLVMFuzzerCustomMutator: BINGO
diff --git a/test/fuzzer/fuzzer-dict.test b/test/fuzzer/fuzzer-dict.test
index 48c91dc1d6fe..d396f6950a13 100644
--- a/test/fuzzer/fuzzer-dict.test
+++ b/test/fuzzer/fuzzer-dict.test
@@ -3,6 +3,6 @@ RUN: %cpp_compiler %S/SimpleDictionaryTest.cpp -o %t-SimpleDictionaryTest
CHECK: BINGO
Done1000000: Done 1000000 runs in
-RUN: not %t-SimpleDictionaryTest -dict=%S/dict1.txt -seed=1 -runs=1000003 2>&1 | FileCheck %s
-RUN: %t-SimpleDictionaryTest -seed=1 -runs=1000000 2>&1 | FileCheck %s --check-prefix=Done1000000
+RUN: not %run %t-SimpleDictionaryTest -dict=%S/dict1.txt -seed=1 -runs=1000003 2>&1 | FileCheck %s
+RUN: %run %t-SimpleDictionaryTest -seed=1 -runs=1000000 2>&1 | FileCheck %s --check-prefix=Done1000000
diff --git a/test/fuzzer/fuzzer-dirs.test b/test/fuzzer/fuzzer-dirs.test
index 9b6e4d1eedda..3c742b52da4c 100644
--- a/test/fuzzer/fuzzer-dirs.test
+++ b/test/fuzzer/fuzzer-dirs.test
@@ -5,17 +5,17 @@ RUN: mkdir -p %t/SUB1/SUB2/SUB3
RUN: echo a > %t/SUB1/a
RUN: echo b > %t/SUB1/SUB2/b
RUN: echo c > %t/SUB1/SUB2/SUB3/c
-RUN: %t-SimpleTest %t/SUB1 -runs=0 2>&1 | FileCheck %s --check-prefix=SUBDIRS
+RUN: %run %t-SimpleTest %t/SUB1 -runs=0 2>&1 | FileCheck %s --check-prefix=SUBDIRS
SUBDIRS: INFO: seed corpus: files: 3 min: 2b max: 2b total: 6b
RUN: echo -n zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz > %t/SUB1/f64
RUN: cat %t/SUB1/f64 %t/SUB1/f64 %t/SUB1/f64 %t/SUB1/f64 > %t/SUB1/f256
RUN: cat %t/SUB1/f256 %t/SUB1/f256 %t/SUB1/f256 %t/SUB1/f256 > %t/SUB1/f1024
RUN: cat %t/SUB1/f1024 %t/SUB1/f1024 %t/SUB1/f1024 %t/SUB1/f1024 > %t/SUB1/f4096
RUN: cat %t/SUB1/f4096 %t/SUB1/f4096 > %t/SUB1/f8192
-RUN: %t-SimpleTest %t/SUB1 -runs=0 2>&1 | FileCheck %s --check-prefix=LONG
+RUN: %run %t-SimpleTest %t/SUB1 -runs=0 2>&1 | FileCheck %s --check-prefix=LONG
LONG: INFO: -max_len is not provided; libFuzzer will not generate inputs larger than 8192 bytes
RUN: rm -rf %t/SUB1
-RUN: not %t-SimpleTest NONEXISTENT_DIR 2>&1 | FileCheck %s --check-prefix=NONEXISTENT_DIR
-NONEXISTENT_DIR: No such directory: NONEXISTENT_DIR; exiting
+RUN: not %run %t-SimpleTest NONEXISTENT_DIR 2>&1 | FileCheck %s --check-prefix=NONEXISTENT_DIR
+NONEXISTENT_DIR: No such file or directory: NONEXISTENT_DIR; exiting
diff --git a/test/fuzzer/fuzzer-fdmask.test b/test/fuzzer/fuzzer-fdmask.test
index 3f04993b5d7e..09f29782b8a8 100644
--- a/test/fuzzer/fuzzer-fdmask.test
+++ b/test/fuzzer/fuzzer-fdmask.test
@@ -1,28 +1,28 @@
RUN: %cpp_compiler %S/SpamyTest.cpp -o %t-SpamyTest
-RUN: %t-SpamyTest -runs=1 2>&1 | FileCheck %s --check-prefix=FD_MASK_0
-RUN: %t-SpamyTest -runs=1 -close_fd_mask=0 2>&1 | FileCheck %s --check-prefix=FD_MASK_0
-RUN: %t-SpamyTest -runs=1 -close_fd_mask=1 2>&1 | FileCheck %s --check-prefix=FD_MASK_1
-RUN: %t-SpamyTest -runs=1 -close_fd_mask=2 2>&1 | FileCheck %s --check-prefix=FD_MASK_2
-RUN: %t-SpamyTest -runs=1 -close_fd_mask=3 2>&1 | FileCheck %s --check-prefix=FD_MASK_3
+RUN: %run %t-SpamyTest -runs=1 2>&1 | FileCheck %s --check-prefix=FD_MASK_0
+RUN: %run %t-SpamyTest -runs=1 -close_fd_mask=0 2>&1 | FileCheck %s --check-prefix=FD_MASK_0
+RUN: %run %t-SpamyTest -runs=1 -close_fd_mask=1 2>&1 | FileCheck %s --check-prefix=FD_MASK_1
+RUN: %run %t-SpamyTest -runs=1 -close_fd_mask=2 2>&1 | FileCheck %s --check-prefix=FD_MASK_2
+RUN: %run %t-SpamyTest -runs=1 -close_fd_mask=3 2>&1 | FileCheck %s --check-prefix=FD_MASK_3
-FD_MASK_0: PRINTF_STDOUT
-FD_MASK_0: PRINTF_STDERR
-FD_MASK_0: STREAM_COUT
-FD_MASK_0: STREAM_CERR
-FD_MASK_0: INITED
+FD_MASK_0-DAG: PRINTF_STDOUT
+FD_MASK_0-DAG: PRINTF_STDERR
+FD_MASK_0-DAG: STREAM_COUT
+FD_MASK_0-DAG: STREAM_CERR
+FD_MASK_0-DAG: INITED
FD_MASK_1-NOT: PRINTF_STDOUT
-FD_MASK_1: PRINTF_STDERR
+FD_MASK_1-DAG: PRINTF_STDERR
FD_MASK_1-NOT: STREAM_COUT
-FD_MASK_1: STREAM_CERR
-FD_MASK_1: INITED
+FD_MASK_1-DAG: STREAM_CERR
+FD_MASK_1-DAG: INITED
-FD_MASK_2: PRINTF_STDOUT
+FD_MASK_2-DAG: PRINTF_STDOUT
+FD_MASK_2-DAG: STREAM_COUT
+FD_MASK_2-DAG: INITED
FD_MASK_2-NOT: PRINTF_STDERR
-FD_MASK_2: STREAM_COUT
-FD_MASK_2-NOTE: STREAM_CERR
-FD_MASK_2: INITED
+FD_MASK_2-NOT: STREAM_CERR
FD_MASK_3-NOT: PRINTF_STDOUT
FD_MASK_3-NOT: PRINTF_STDERR
diff --git a/test/fuzzer/fuzzer-finalstats.test b/test/fuzzer/fuzzer-finalstats.test
index 4f983bea825e..d8c991e30847 100644
--- a/test/fuzzer/fuzzer-finalstats.test
+++ b/test/fuzzer/fuzzer-finalstats.test
@@ -1,12 +1,12 @@
RUN: %cpp_compiler %S/SimpleTest.cpp -o %t-SimpleTest
-RUN: %t-SimpleTest -seed=1 -runs=77 -print_final_stats=1 2>&1 | FileCheck %s --check-prefix=FINAL_STATS
+RUN: %run %t-SimpleTest -seed=1 -runs=77 -print_final_stats=1 2>&1 | FileCheck %s --check-prefix=FINAL_STATS
FINAL_STATS: stat::number_of_executed_units: 77
FINAL_STATS: stat::average_exec_per_sec: 0
FINAL_STATS: stat::new_units_added:
FINAL_STATS: stat::slowest_unit_time_sec: 0
FINAL_STATS: stat::peak_rss_mb:
-RUN: %t-SimpleTest %S/dict1.txt -runs=33 -print_final_stats=1 2>&1 | FileCheck %s --check-prefix=FINAL_STATS1
+RUN: %run %t-SimpleTest %S/dict1.txt -runs=33 -print_final_stats=1 2>&1 | FileCheck %s --check-prefix=FINAL_STATS1
FINAL_STATS1: stat::number_of_executed_units: 33
FINAL_STATS1: stat::peak_rss_mb:
diff --git a/test/fuzzer/fuzzer-flags.test b/test/fuzzer/fuzzer-flags.test
index b812b01695d8..916c6eed889f 100644
--- a/test/fuzzer/fuzzer-flags.test
+++ b/test/fuzzer/fuzzer-flags.test
@@ -1,19 +1,19 @@
RUN: %cpp_compiler %S/FlagsTest.cpp -o %t-FlagsTest
-RUN: %t-FlagsTest -runs=10 -foo_bar=1 2>&1 | FileCheck %s --check-prefix=FOO_BAR
+RUN: %run %t-FlagsTest -runs=10 -foo_bar=1 2>&1 | FileCheck %s --check-prefix=FOO_BAR
FOO_BAR: WARNING: unrecognized flag '-foo_bar=1'; use -help=1 to list all flags
FOO_BAR: BINGO
-RUN: %t-FlagsTest -runs=10 --max_len=100 2>&1 | FileCheck %s --check-prefix=DASH_DASH
+RUN: %run %t-FlagsTest -runs=10 --max_len=100 2>&1 | FileCheck %s --check-prefix=DASH_DASH
DASH_DASH: WARNING: did you mean '-max_len=100' (single dash)?
DASH_DASH: INFO: A corpus is not provided, starting from an empty corpus
-RUN: %t-FlagsTest -help=1 2>&1 | FileCheck %s --check-prefix=NO_INTERNAL
+RUN: %run %t-FlagsTest -help=1 2>&1 | FileCheck %s --check-prefix=NO_INTERNAL
NO_INTERNAL-NOT: internal flag
-RUN: %t-FlagsTest --foo-bar -runs=10 -ignore_remaining_args=1 --baz -help=1 test 2>&1 | FileCheck %s --check-prefix=PASSTHRU
+RUN: %run %t-FlagsTest --foo-bar -runs=10 -ignore_remaining_args=1 --baz -help=1 test 2>&1 | FileCheck %s --check-prefix=PASSTHRU
PASSTHRU: BINGO --foo-bar --baz -help=1 test
RUN: mkdir -p %t/T0 %t/T1
RUN: echo z > %t/T1/z
-RUN: %t-FlagsTest -runs=10 --foo-bar -merge=1 %t/T0 %t/T1 -ignore_remaining_args=1 --baz -help=1 test 2>&1 | FileCheck %s --check-prefix=PASSTHRU-MERGE
+RUN: %run %t-FlagsTest -runs=10 --foo-bar -merge=1 %t/T0 %t/T1 -ignore_remaining_args=1 --baz -help=1 test 2>&1 | FileCheck %s --check-prefix=PASSTHRU-MERGE
PASSTHRU-MERGE: BINGO --foo-bar --baz -help=1 test
diff --git a/test/fuzzer/fuzzer-leak.test b/test/fuzzer/fuzzer-leak.test
index 0652a88f9d5d..2b61811d5d1b 100644
--- a/test/fuzzer/fuzzer-leak.test
+++ b/test/fuzzer/fuzzer-leak.test
@@ -1,10 +1,11 @@
REQUIRES: lsan
+
RUN: %cpp_compiler %S/LeakTest.cpp -o %t-LeakTest
RUN: %cpp_compiler %S/ThreadedLeakTest.cpp -o %t-ThreadedLeakTest
RUN: %cpp_compiler %S/LeakTimeoutTest.cpp -o %t-LeakTimeoutTest
RUN: rm -rf %t-corpus && mkdir -p %t-corpus
-RUN: not %t-LeakTest -runs=100000 -detect_leaks=1 %t-corpus 2>&1 | FileCheck %s --check-prefix=LEAK_DURING
+RUN: not %run %t-LeakTest -runs=100000 -detect_leaks=1 %t-corpus 2>&1 | FileCheck %s --check-prefix=LEAK_DURING
LEAK_DURING: ERROR: LeakSanitizer: detected memory leaks
LEAK_DURING: Direct leak of 4 byte(s) in 1 object(s) allocated from:
LEAK_DURING: INFO: to ignore leaks on libFuzzer side use -detect_leaks=0
@@ -13,29 +14,29 @@ LEAK_DURING-NOT: DONE
LEAK_DURING-NOT: Done
// Verify leaking input was not added to corpus
-RUN: %t-LeakTest -runs=0 %t-corpus
+RUN: %run %t-LeakTest -runs=0 %t-corpus
-RUN: not %t-LeakTest -runs=0 -detect_leaks=1 %S 2>&1 | FileCheck %s --check-prefix=LEAK_IN_CORPUS
+RUN: not %run %t-LeakTest -runs=0 -detect_leaks=1 %S 2>&1 | FileCheck %s --check-prefix=LEAK_IN_CORPUS
LEAK_IN_CORPUS: ERROR: LeakSanitizer: detected memory leaks
LEAK_IN_CORPUS: INFO: a leak has been found in the initial corpus.
-RUN: not %t-LeakTest -runs=100000000 %S/hi.txt 2>&1 | FileCheck %s --check-prefix=MULTI_RUN_LEAK
+RUN: not %run %t-LeakTest -runs=100000000 %S/hi.txt 2>&1 | FileCheck %s --check-prefix=MULTI_RUN_LEAK
MULTI_RUN_LEAK-NOT: pulse
MULTI_RUN_LEAK: LeakSanitizer: detected memory leaks
-RUN: not %t-LeakTest -runs=100000 -detect_leaks=0 2>&1 | FileCheck %s --check-prefix=LEAK_AFTER
-RUN: not %t-LeakTest -runs=100000 2>&1 | FileCheck %s --check-prefix=LEAK_DURING
-RUN: not %t-ThreadedLeakTest -runs=100000 -detect_leaks=0 2>&1 | FileCheck %s --check-prefix=LEAK_AFTER
-RUN: not %t-ThreadedLeakTest -runs=100000 2>&1 | FileCheck %s --check-prefix=LEAK_DURING
+RUN: not %run %t-LeakTest -runs=100000 -detect_leaks=0 2>&1 | FileCheck %s --check-prefix=LEAK_AFTER
+RUN: not %run %t-LeakTest -runs=100000 2>&1 | FileCheck %s --check-prefix=LEAK_DURING
+RUN: not %run %t-ThreadedLeakTest -runs=100000 -detect_leaks=0 2>&1 | FileCheck %s --check-prefix=LEAK_AFTER
+RUN: not %run %t-ThreadedLeakTest -runs=100000 2>&1 | FileCheck %s --check-prefix=LEAK_DURING
LEAK_AFTER: Done 100000 runs in
LEAK_AFTER: ERROR: LeakSanitizer: detected memory leaks
-RUN: not %t-LeakTest -runs=100000 -max_len=1 2>&1 | FileCheck %s --check-prefix=MAX_LEN_1
+RUN: not %run %t-LeakTest -runs=100000 -max_len=1 2>&1 | FileCheck %s --check-prefix=MAX_LEN_1
MAX_LEN_1: Test unit written to ./leak-7cf184f4c67ad58283ecb19349720b0cae756829
-RUN: not %t-LeakTimeoutTest -timeout=1 2>&1 | FileCheck %s --check-prefix=LEAK_TIMEOUT
+RUN: not %run %t-LeakTimeoutTest -timeout=1 2>&1 | FileCheck %s --check-prefix=LEAK_TIMEOUT
LEAK_TIMEOUT: ERROR: libFuzzer: timeout after
LEAK_TIMEOUT-NOT: LeakSanitizer
-RUN: %t-LeakTest -error_exitcode=0
+RUN: %run %t-LeakTest -error_exitcode=0
diff --git a/test/fuzzer/fuzzer-mutationstats.test b/test/fuzzer/fuzzer-mutationstats.test
new file mode 100644
index 000000000000..95743a818d1f
--- /dev/null
+++ b/test/fuzzer/fuzzer-mutationstats.test
@@ -0,0 +1,5 @@
+RUN: %cpp_compiler %S/SimpleTest.cpp -o %t-MutationStatsTest
+RUN: not %run %t-MutationStatsTest -print_mutation_stats=1 2>&1 | FileCheck %s
+
+# Ensures there are some non-zero values in the usefulness percentages printed.
+CHECK: stat::mutation_usefulness: {{[0-9]+\.[0-9]+}}
diff --git a/test/fuzzer/fuzzer-oom-with-profile.test b/test/fuzzer/fuzzer-oom-with-profile.test
index 75cf48430a46..918197abd5a2 100644
--- a/test/fuzzer/fuzzer-oom-with-profile.test
+++ b/test/fuzzer/fuzzer-oom-with-profile.test
@@ -1,6 +1,6 @@
REQUIRES: linux
RUN: %cpp_compiler %S/OutOfMemoryTest.cpp -o %t-OutOfMemoryTest
-RUN: not %t-OutOfMemoryTest -rss_limit_mb=300 2>&1 | FileCheck %s
+RUN: not %run %t-OutOfMemoryTest -rss_limit_mb=300 2>&1 | FileCheck %s
CHECK: ERROR: libFuzzer: out-of-memory (used: {{.*}}; limit: 300Mb)
CHECK: Live Heap Allocations
CHECK: Test unit written to ./oom-
diff --git a/test/fuzzer/fuzzer-oom.test b/test/fuzzer/fuzzer-oom.test
index 308c4c5cd394..e82fb47c5bed 100644
--- a/test/fuzzer/fuzzer-oom.test
+++ b/test/fuzzer/fuzzer-oom.test
@@ -1,16 +1,17 @@
+UNSUPPORTED: aarch64
RUN: %cpp_compiler %S/OutOfMemoryTest.cpp -o %t-OutOfMemoryTest
RUN: %cpp_compiler %S/OutOfMemorySingleLargeMallocTest.cpp -o %t-OutOfMemorySingleLargeMallocTest
RUN: %cpp_compiler %S/AccumulateAllocationsTest.cpp -o %t-AccumulateAllocationsTest
-RUN: not %t-OutOfMemoryTest -rss_limit_mb=300 2>&1 | FileCheck %s
+RUN: not %run %t-OutOfMemoryTest -rss_limit_mb=300 2>&1 | FileCheck %s
CHECK: ERROR: libFuzzer: out-of-memory (used: {{.*}}; limit: 300Mb)
CHECK: Test unit written to ./oom-
SUMMARY: libFuzzer: out-of-memory
-RUN: not %t-OutOfMemorySingleLargeMallocTest -rss_limit_mb=300 2>&1 | FileCheck %s --check-prefix=SINGLE_LARGE_MALLOC
-RUN: not %t-OutOfMemorySingleLargeMallocTest -malloc_limit_mb=300 2>&1 | FileCheck %s --check-prefix=SINGLE_LARGE_MALLOC
-RUN: not %t-OutOfMemorySingleLargeMallocTest -rss_limit_mb=1000 -malloc_limit_mb=300 2>&1 | FileCheck %s --check-prefix=SINGLE_LARGE_MALLOC
+RUN: not %run %t-OutOfMemorySingleLargeMallocTest -rss_limit_mb=300 2>&1 | FileCheck %s --check-prefix=SINGLE_LARGE_MALLOC
+RUN: not %run %t-OutOfMemorySingleLargeMallocTest -malloc_limit_mb=300 2>&1 | FileCheck %s --check-prefix=SINGLE_LARGE_MALLOC
+RUN: not %run %t-OutOfMemorySingleLargeMallocTest -rss_limit_mb=1000 -malloc_limit_mb=300 2>&1 | FileCheck %s --check-prefix=SINGLE_LARGE_MALLOC
We used to check for "out-of-memory (malloc(53{{.*}}))", but that would fail
sometimes, so now we accept any OOM message.
@@ -19,4 +20,4 @@ SINGLE_LARGE_MALLOC: libFuzzer: out-of-memory
SINGLE_LARGE_MALLOC: in LLVMFuzzerTestOneInput
# Check that -rss_limit_mb=0 means no limit.
-RUN: %t-AccumulateAllocationsTest -runs=1000 -rss_limit_mb=0
+RUN: %run %t-AccumulateAllocationsTest -runs=1000 -rss_limit_mb=0
diff --git a/test/fuzzer/fuzzer-printcovpcs.test b/test/fuzzer/fuzzer-printcovpcs.test
index e55ce14aa72f..decf0a7e5fff 100644
--- a/test/fuzzer/fuzzer-printcovpcs.test
+++ b/test/fuzzer/fuzzer-printcovpcs.test
@@ -1,5 +1,7 @@
+XFAIL: ios
+UNSUPPORTED: aarch64
RUN: %cpp_compiler %S/SimpleTest.cpp -o %t-SimpleTest
-RUN: not %t-SimpleTest -print_pcs=1 -seed=1 2>&1 | FileCheck %s --check-prefix=PCS
+RUN: not %run %t-SimpleTest -print_pcs=1 -seed=1 2>&1 | FileCheck %s --check-prefix=PCS
PCS-NOT: NEW_PC
PCS:INITED
PCS:NEW_PC: {{0x[a-f0-9]+}}
diff --git a/test/fuzzer/fuzzer-runs.test b/test/fuzzer/fuzzer-runs.test
index 04987eee5029..b3f20c475aa9 100644
--- a/test/fuzzer/fuzzer-runs.test
+++ b/test/fuzzer/fuzzer-runs.test
@@ -1,9 +1,9 @@
RUN: mkdir -p %t
RUN: %cpp_compiler %S/NthRunCrashTest.cpp -o %t-NthRunCrashTest
RUN: echo abcd > %t/NthRunCrashTest.in
-RUN: %t-NthRunCrashTest %t/NthRunCrashTest.in
-RUN: %t-NthRunCrashTest %t/NthRunCrashTest.in -runs=10
-RUN: not %t-NthRunCrashTest %t/NthRunCrashTest.in -runs=10000 2>&1 | FileCheck %s
+RUN: %run %t-NthRunCrashTest %t/NthRunCrashTest.in
+RUN: %run %t-NthRunCrashTest %t/NthRunCrashTest.in -runs=10
+RUN: not %run %t-NthRunCrashTest %t/NthRunCrashTest.in -runs=10000 2>&1 | FileCheck %s
RUN: rm %t/NthRunCrashTest.in
CHECK: BINGO
diff --git a/test/fuzzer/fuzzer-seed.test b/test/fuzzer/fuzzer-seed.test
index a69ea5432849..b6343ffa3dd7 100644
--- a/test/fuzzer/fuzzer-seed.test
+++ b/test/fuzzer/fuzzer-seed.test
@@ -1,4 +1,4 @@
RUN: %cpp_compiler %S/NullDerefTest.cpp -o %t-SimpleCmpTest
-RUN: %t-SimpleCmpTest -seed=-1 -runs=0 2>&1 | FileCheck %s --check-prefix=CHECK_SEED_MINUS_ONE
+RUN: %run %t-SimpleCmpTest -seed=-1 -runs=0 2>&1 | FileCheck %s --check-prefix=CHECK_SEED_MINUS_ONE
CHECK_SEED_MINUS_ONE: Seed: 4294967295
diff --git a/test/fuzzer/fuzzer-segv.test b/test/fuzzer/fuzzer-segv.test
index 4d3c7575f7a8..0c4fafe08077 100644
--- a/test/fuzzer/fuzzer-segv.test
+++ b/test/fuzzer/fuzzer-segv.test
@@ -1,8 +1,8 @@
RUN: %cpp_compiler %S/NullDerefTest.cpp -o %t-NullDerefTest
-RUN: env ASAN_OPTIONS=handle_segv=0 not %t-NullDerefTest 2>&1 | FileCheck %s --check-prefix=LIBFUZZER_OWN_SEGV_HANDLER
+RUN: env ASAN_OPTIONS=handle_segv=0 not %run %t-NullDerefTest 2>&1 | FileCheck %s --check-prefix=LIBFUZZER_OWN_SEGV_HANDLER
LIBFUZZER_OWN_SEGV_HANDLER: == ERROR: libFuzzer: deadly signal
LIBFUZZER_OWN_SEGV_HANDLER: SUMMARY: libFuzzer: deadly signal
LIBFUZZER_OWN_SEGV_HANDLER: Test unit written to ./crash-
-RUN: env ASAN_OPTIONS=handle_segv=1 not %t-NullDerefTest 2>&1 | FileCheck %s --check-prefix=LIBFUZZER_ASAN_SEGV_HANDLER
+RUN: env ASAN_OPTIONS=handle_segv=1 not %run %t-NullDerefTest 2>&1 | FileCheck %s --check-prefix=LIBFUZZER_ASAN_SEGV_HANDLER
LIBFUZZER_ASAN_SEGV_HANDLER: ERROR: AddressSanitizer: {{SEGV|access-violation}} on unknown address
diff --git a/test/fuzzer/fuzzer-singleinputs.test b/test/fuzzer/fuzzer-singleinputs.test
index 468da5622af9..704f9caa57f9 100644
--- a/test/fuzzer/fuzzer-singleinputs.test
+++ b/test/fuzzer/fuzzer-singleinputs.test
@@ -1,15 +1,15 @@
RUN: %cpp_compiler %S/NullDerefTest.cpp -o %t-NullDerefTest
RUN: %cpp_compiler %S/SimpleTest.cpp -o %t-SimpleTest
-RUN: not %t-NullDerefTest %S/hi.txt 2>&1 | FileCheck %s --check-prefix=SingleInput
+RUN: not %run %t-NullDerefTest %S/hi.txt 2>&1 | FileCheck %s --check-prefix=SingleInput
SingleInput-NOT: Test unit written to ./crash-
RUN: rm -rf %tmp/SINGLE_INPUTS
RUN: mkdir -p %tmp/SINGLE_INPUTS
RUN: echo aaa > %tmp/SINGLE_INPUTS/aaa
RUN: echo bbb > %tmp/SINGLE_INPUTS/bbb
-RUN: %t-SimpleTest %tmp/SINGLE_INPUTS/aaa %tmp/SINGLE_INPUTS/bbb 2>&1 | FileCheck %s --check-prefix=SINGLE_INPUTS
-RUN: %t-SimpleTest -max_len=2 %tmp/SINGLE_INPUTS/aaa %tmp/SINGLE_INPUTS/bbb 2>&1 | FileCheck %s --check-prefix=SINGLE_INPUTS
+RUN: %run %t-SimpleTest %tmp/SINGLE_INPUTS/aaa %tmp/SINGLE_INPUTS/bbb 2>&1 | FileCheck %s --check-prefix=SINGLE_INPUTS
+RUN: %run %t-SimpleTest -max_len=2 %tmp/SINGLE_INPUTS/aaa %tmp/SINGLE_INPUTS/bbb 2>&1 | FileCheck %s --check-prefix=SINGLE_INPUTS
RUN: rm -rf %tmp/SINGLE_INPUTS
SINGLE_INPUTS: SimpleTest{{.*}}: Running 2 inputs 1 time(s) each.
SINGLE_INPUTS: aaa in
diff --git a/test/fuzzer/fuzzer-threaded.test b/test/fuzzer/fuzzer-threaded.test
index 572ed5a35518..3321e19585c0 100644
--- a/test/fuzzer/fuzzer-threaded.test
+++ b/test/fuzzer/fuzzer-threaded.test
@@ -1,8 +1,8 @@
CHECK: Done 1000 runs in
RUN: %cpp_compiler %S/ThreadedTest.cpp -o %t-ThreadedTest
-RUN: %t-ThreadedTest -use_traces=1 -runs=1000 2>&1 | FileCheck %s
-RUN: %t-ThreadedTest -use_traces=1 -runs=1000 2>&1 | FileCheck %s
-RUN: %t-ThreadedTest -use_traces=1 -runs=1000 2>&1 | FileCheck %s
-RUN: %t-ThreadedTest -use_traces=1 -runs=1000 2>&1 | FileCheck %s
+RUN: %run %t-ThreadedTest -use_traces=1 -runs=1000 2>&1 | FileCheck %s
+RUN: %run %t-ThreadedTest -use_traces=1 -runs=1000 2>&1 | FileCheck %s
+RUN: %run %t-ThreadedTest -use_traces=1 -runs=1000 2>&1 | FileCheck %s
+RUN: %run %t-ThreadedTest -use_traces=1 -runs=1000 2>&1 | FileCheck %s
diff --git a/test/fuzzer/fuzzer-timeout.test b/test/fuzzer/fuzzer-timeout.test
index 41f4ba364398..a924cde73373 100644
--- a/test/fuzzer/fuzzer-timeout.test
+++ b/test/fuzzer/fuzzer-timeout.test
@@ -1,6 +1,6 @@
RUN: %cpp_compiler %S/TimeoutTest.cpp -o %t-TimeoutTest
RUN: %cpp_compiler %S/TimeoutEmptyTest.cpp -o %t-TimeoutEmptyTest
-RUN: not %t-TimeoutTest -timeout=1 2>&1 | FileCheck %s --check-prefix=TimeoutTest
+RUN: not %run %t-TimeoutTest -timeout=1 2>&1 | FileCheck %s --check-prefix=TimeoutTest
TimeoutTest: ALARM: working on the last Unit for
TimeoutTest: Test unit written to ./timeout-
TimeoutTest: == ERROR: libFuzzer: timeout after
@@ -9,13 +9,13 @@ TimeoutTest: #1
TimeoutTest: #2
TimeoutTest: SUMMARY: libFuzzer: timeout
-RUN: not %t-TimeoutTest -timeout=1 %S/hi.txt 2>&1 | FileCheck %s --check-prefix=SingleInputTimeoutTest
+RUN: not %run %t-TimeoutTest -timeout=1 %S/hi.txt 2>&1 | FileCheck %s --check-prefix=SingleInputTimeoutTest
SingleInputTimeoutTest: ALARM: working on the last Unit for {{[1-3]}} seconds
SingleInputTimeoutTest-NOT: Test unit written to ./timeout-
-RUN: %t-TimeoutTest -timeout=1 -timeout_exitcode=0
+RUN: %run %t-TimeoutTest -timeout=1 -timeout_exitcode=0
-RUN: not %t-TimeoutEmptyTest -timeout=1 2>&1 | FileCheck %s --check-prefix=TimeoutEmptyTest
+RUN: not %run %t-TimeoutEmptyTest -timeout=1 2>&1 | FileCheck %s --check-prefix=TimeoutEmptyTest
TimeoutEmptyTest: ALARM: working on the last Unit for
TimeoutEmptyTest: == ERROR: libFuzzer: timeout after
TimeoutEmptyTest: SUMMARY: libFuzzer: timeout
diff --git a/test/fuzzer/fuzzer-ubsan.test b/test/fuzzer/fuzzer-ubsan.test
index 49c190cd034b..6bc2c3863668 100644
--- a/test/fuzzer/fuzzer-ubsan.test
+++ b/test/fuzzer/fuzzer-ubsan.test
@@ -1,5 +1,5 @@
RUN: %cpp_compiler -fsanitize=undefined -fno-sanitize-recover=all %S/SignedIntOverflowTest.cpp -o %t-SignedIntOverflowTest-Ubsan
-RUN: not %t-SignedIntOverflowTest-Ubsan 2>&1 | FileCheck %s
+RUN: not %run %t-SignedIntOverflowTest-Ubsan 2>&1 | FileCheck %s
CHECK: runtime error: signed integer overflow: 2147483647 + 1 cannot be represented in type 'int'
CHECK: Test unit written to ./crash-
diff --git a/test/fuzzer/fuzzer.test b/test/fuzzer/fuzzer.test
deleted file mode 100644
index 29bc8f0ce795..000000000000
--- a/test/fuzzer/fuzzer.test
+++ /dev/null
@@ -1,70 +0,0 @@
-CHECK: BINGO
-Done1000000: Done 1000000 runs in
-RUN: %cpp_compiler %S/BogusInitializeTest.cpp -o %t-BogusInitializeTest
-RUN: %cpp_compiler %S/BufferOverflowOnInput.cpp -o %t-BufferOverflowOnInput
-RUN: %cpp_compiler %S/CounterTest.cpp -o %t-CounterTest
-RUN: %cpp_compiler %S/DSO1.cpp -fPIC -shared -o %t-DSO1.so
-RUN: %cpp_compiler %S/DSO2.cpp -fPIC -shared -o %t-DSO2.so
-RUN: %cpp_compiler %S/DSOTestMain.cpp %S/DSOTestExtra.cpp -L. %t-DSO1.so %t-DSO2.so -o %t-DSOTest
-RUN: %cpp_compiler %S/FullCoverageSetTest.cpp -o %t-FullCoverageSetTest
-RUN: %cpp_compiler %S/InitializeTest.cpp -o %t-InitializeTest
-RUN: %cpp_compiler %S/NotinstrumentedTest.cpp -fsanitize-coverage=0 -o %t-NotinstrumentedTest-NoCoverage
-RUN: %cpp_compiler %S/NullDerefOnEmptyTest.cpp -o %t-NullDerefOnEmptyTest
-RUN: %cpp_compiler %S/NullDerefTest.cpp -o %t-NullDerefTest
-RUN: %cpp_compiler %S/SimpleCmpTest.cpp -o %t-SimpleCmpTest
-RUN: %cpp_compiler %S/SimpleTest.cpp -o %t-SimpleTest
-RUN: %cpp_compiler %S/StrncmpOOBTest.cpp -o %t-StrncmpOOBTest
-
-RUN: not %t-SimpleTest 2>&1 | FileCheck %s
-
-# only_ascii mode. Will perform some minimal self-validation.
-RUN: not %t-SimpleTest -only_ascii=1 2>&1
-
-RUN: %t-SimpleCmpTest -max_total_time=1 -use_cmp=0 2>&1 | FileCheck %s --check-prefix=MaxTotalTime
-MaxTotalTime: Done {{.*}} runs in {{.}} second(s)
-
-RUN: not %t-NullDerefTest 2>&1 | FileCheck %s --check-prefix=NullDerefTest
-RUN: not %t-NullDerefTest -close_fd_mask=3 2>&1 | FileCheck %s --check-prefix=NullDerefTest
-NullDerefTest: ERROR: AddressSanitizer: {{SEGV|access-violation}} on unknown address
-NullDerefTest: Test unit written to ./crash-
-RUN: not %t-NullDerefTest -artifact_prefix=ZZZ 2>&1 | FileCheck %s --check-prefix=NullDerefTestPrefix
-NullDerefTestPrefix: Test unit written to ZZZcrash-
-RUN: not %t-NullDerefTest -artifact_prefix=ZZZ -exact_artifact_path=FOOBAR 2>&1 | FileCheck %s --check-prefix=NullDerefTestExactPath
-NullDerefTestExactPath: Test unit written to FOOBAR
-
-RUN: not %t-NullDerefOnEmptyTest -print_final_stats=1 2>&1 | FileCheck %s --check-prefix=NULL_DEREF_ON_EMPTY
-NULL_DEREF_ON_EMPTY: stat::number_of_executed_units:
-
-#not %t-FullCoverageSetTest -timeout=15 -seed=1 -mutate_depth=2 -use_full_coverage_set=1 2>&1 | FileCheck %s
-
-RUN: not %t-CounterTest -max_len=6 -seed=1 -timeout=15 2>&1 | FileCheck %s --check-prefix=COUNTERS
-
-COUNTERS: INITED {{.*}} {{bits:|ft:}}
-COUNTERS: NEW {{.*}} {{bits:|ft:}} {{[1-9]*}}
-COUNTERS: NEW {{.*}} {{bits:|ft:}} {{[1-9]*}}
-COUNTERS: BINGO
-
-# Don't run UninstrumentedTest for now since we build libFuzzer itself with asan.
-DISABLED: not %t-UninstrumentedTest-Uninstrumented 2>&1 | FileCheck %s --check-prefix=UNINSTRUMENTED
-UNINSTRUMENTED: ERROR: __sanitizer_set_death_callback is not defined. Exiting.
-
-RUN: not %t-NotinstrumentedTest-NoCoverage 2>&1 | FileCheck %s --check-prefix=NO_COVERAGE
-NO_COVERAGE: ERROR: no interesting inputs were found. Is the code instrumented for coverage? Exiting
-
-RUN: not %t-BufferOverflowOnInput 2>&1 | FileCheck %s --check-prefix=OOB
-OOB: AddressSanitizer: heap-buffer-overflow
-OOB: is located 0 bytes to the right of 3-byte region
-
-RUN: not %t-InitializeTest -use_value_profile=1 2>&1 | FileCheck %s
-
-RUN: not %t-DSOTest 2>&1 | FileCheck %s --check-prefix=DSO
-DSO: INFO: Loaded 3 modules
-DSO: BINGO
-
-RUN: env ASAN_OPTIONS=strict_string_checks=1 not %t-StrncmpOOBTest -seed=1 -runs=1000000 2>&1 | FileCheck %s --check-prefix=STRNCMP
-STRNCMP: AddressSanitizer: heap-buffer-overflow
-STRNCMP-NOT: __sanitizer_weak_hook_strncmp
-STRNCMP: in LLVMFuzzerTestOneInput
-
-RUN: not %t-BogusInitializeTest 2>&1 | FileCheck %s --check-prefix=BOGUS_INITIALIZE
-BOGUS_INITIALIZE: argv[0] has been modified in LLVMFuzzerInitialize
diff --git a/test/fuzzer/gc-sections.test b/test/fuzzer/gc-sections.test
index 8785bb00ec1b..b8abfbbdf17b 100644
--- a/test/fuzzer/gc-sections.test
+++ b/test/fuzzer/gc-sections.test
@@ -1,12 +1,14 @@
-REQUIRES: linux
+REQUIRES: linux, lld-available
No gc-sections:
RUN: %cpp_compiler %S/GcSectionsTest.cpp -o %t
RUN: nm %t | grep UnusedFunctionShouldBeRemovedByLinker | count 1
-With gc-sections. Currently, we can't remove unused code.
-DISABLED: %cpp_compiler %S/GcSectionsTest.cpp -o %t -ffunction-sections -Wl,-gc-sections
-DISABLED: nm %t | grep UnusedFunctionShouldBeRemovedByLinker | count 1
+With gc-sections. Currently, we can't remove unused code except with LLD.
+RUN: %cpp_compiler %S/GcSectionsTest.cpp -o %t -fuse-ld=lld -ffunction-sections -Wl,-gc-sections
+RUN: nm %t | not grep UnusedFunctionShouldBeRemovedByLinker
+RUN: %run %t -runs=0 2>&1 | FileCheck %s
+CHECK-NOT: ERROR: The size of coverage PC tables does not match
With gc sections, with trace-pc. Unused code is removed.
RUN: %cpp_compiler %S/GcSectionsTest.cpp -o %t -fsanitize-coverage=0 -fsanitize-coverage=trace-pc -ffunction-sections -Wl,-gc-sections
diff --git a/test/fuzzer/handle-unstable.test b/test/fuzzer/handle-unstable.test
new file mode 100644
index 000000000000..798ee2dc042f
--- /dev/null
+++ b/test/fuzzer/handle-unstable.test
@@ -0,0 +1,42 @@
+# Tests -handle_unstable
+UNSUPPORTED: aarch64
+
+RUN: %cpp_compiler %S/PrintUnstableStatsTest.cpp -o %t-HandleUnstableTest
+
+; Normal
+RUN: %run %t-HandleUnstableTest -print_coverage=1 -runs=100000 2>&1 | FileCheck %s --check-prefix=NORMAL
+NORMAL-DAG: det0()
+NORMAL-DAG: det1()
+NORMAL-DAG: det2()
+NORMAL-DAG: det3()
+NORMAL-DAG: det4()
+NORMAL-DAG: ini0()
+NORMAL-DAG: ini1()
+NORMAL-DAG: ini2()
+NORMAL-DAG: t0()
+NORMAL-DAG: t1()
+NORMAL-DAG: t2()
+NORMAL-DAG: t3()
+NORMAL-DAG: t4()
+
+; MinUnstable
+RUN: %run %t-HandleUnstableTest -print_coverage=1 -handle_unstable=1 -runs=100000 2>&1 | FileCheck %s --check-prefix=MIN
+MIN-NOT: ini0()
+MIN-NOT: ini1()
+MIN-NOT: ini2()
+MIN: det0()
+MIN: det1()
+MIN: det2()
+MIN: det3()
+MIN: det4()
+
+; ZeroUnstable
+RUN: %run %t-HandleUnstableTest -print_coverage=1 -handle_unstable=2 -runs=1 2>&1 | FileCheck %s --check-prefix=ZERO
+ZERO-NOT: ini0()
+ZERO-NOT: ini1()
+ZERO-NOT: ini2()
+ZERO: det0()
+ZERO: det1()
+ZERO: det2()
+ZERO: det3()
+ZERO: det4()
diff --git a/test/fuzzer/initialize.test b/test/fuzzer/initialize.test
new file mode 100644
index 000000000000..dc6e8697558e
--- /dev/null
+++ b/test/fuzzer/initialize.test
@@ -0,0 +1,3 @@
+CHECK: BINGO
+RUN: %cpp_compiler %S/InitializeTest.cpp -o %t-InitializeTest
+RUN: not %run %t-InitializeTest -use_value_profile=1 2>&1 | FileCheck %s
diff --git a/test/fuzzer/inline-8bit-counters.test b/test/fuzzer/inline-8bit-counters.test
deleted file mode 100644
index 76ae1f537f72..000000000000
--- a/test/fuzzer/inline-8bit-counters.test
+++ /dev/null
@@ -1,4 +0,0 @@
-RUN: %cpp_compiler %S/SimpleTest.cpp -fno-sanitize-coverage=trace-pc-guard -fsanitize-coverage=inline-8bit-counters -o %t-SimpleTest-Inline8bitCounters
-CHECK: INFO: Loaded 1 modules ({{.*}} inline 8-bit counters)
-CHECK: BINGO
-RUN: not %t-SimpleTest-Inline8bitCounters -runs=1000000 -seed=1 2>&1 | FileCheck %s
diff --git a/test/fuzzer/lit.cfg b/test/fuzzer/lit.cfg
index 0350a1ad7797..8a44860d4a5d 100644
--- a/test/fuzzer/lit.cfg
+++ b/test/fuzzer/lit.cfg
@@ -2,7 +2,7 @@ import lit.formats
import sys
import os
-config.name = "LLVMFuzzer"
+config.name = "libFuzzer" + config.name_suffix
config.test_format = lit.formats.ShTest(True)
config.suffixes = ['.test']
config.test_source_root = os.path.dirname(__file__)
@@ -25,12 +25,20 @@ else:
config.test_format = lit.formats.ShTest(execute_external)
# LeakSanitizer is not supported on OSX right now.
-if sys.platform.startswith('darwin'):
+if sys.platform.startswith('darwin') or sys.platform.startswith('freebsd'):
lit_config.note('lsan feature unavailable')
else:
lit_config.note('lsan feature available')
config.available_features.add('lsan')
+# MemorySanitizer is not supported on OSX right now
+if sys.platform.startswith('darwin'):
+ lit_config.note('msan feature unavailable')
+ assert 'msan' not in config.available_features
+else:
+ lit_config.note('msan feature available')
+ config.available_features.add('msan')
+
if sys.platform.startswith('win') or sys.platform.startswith('cygwin'):
config.available_features.add('windows')
@@ -49,18 +57,36 @@ config.substitutions.append(('%build_dir', config.cmake_binary_dir))
libfuzzer_src_root = os.path.join(config.compiler_rt_src_root, "lib", "fuzzer")
config.substitutions.append(('%libfuzzer_src', libfuzzer_src_root))
-def generate_compiler_cmd(is_cpp=True, fuzzer_enabled=True):
- compiler_cmd = config.c_compiler
- link_cmd = '-lc++' if 'darwin' in config.target_triple else '-lstdc++'
- std_cmd = '-std=c++11' if is_cpp else ''
- sanitizers = ['address']
+def generate_compiler_cmd(is_cpp=True, fuzzer_enabled=True, msan_enabled=False):
+ compiler_cmd = config.clang
+ extra_cmd = config.target_flags
+ if config.clang and config.stdlib == 'libc++':
+ link_cmd = '-stdlib=libc++ -Wl,-rpath=%s' % config.runtime_library_dir
+ elif config.clang and config.stdlib == 'static-libc++':
+ link_cmd = '-stdlib=libc++ -lc++abi -static-libstdc++ -Wl,-rpath=%s' % (
+ config.runtime_library_dir)
+ elif any(x in config.target_triple for x in ('darwin', 'freebsd')):
+ link_cmd = '-lc++'
+ else:
+ link_cmd = '-lstdc++'
+
+ std_cmd = '--driver-mode=g++ -std=c++11' if is_cpp else ''
+ if msan_enabled:
+ sanitizers = ['memory']
+ else:
+ sanitizers = ['address']
if fuzzer_enabled:
sanitizers.append('fuzzer')
sanitizers_cmd = ('-fsanitize=%s' % ','.join(sanitizers))
- isysroot_cmd = config.osx_sysroot_flag if config.osx_sysroot_flag else ''
- include_cmd = '-I%s' % libfuzzer_src_root
- return '%s %s %s -gline-tables-only %s %s %s' % (
- compiler_cmd, std_cmd, link_cmd, isysroot_cmd, sanitizers_cmd, include_cmd)
+ return " ".join([
+ compiler_cmd,
+ std_cmd,
+ link_cmd,
+ "-O2 -gline-tables-only",
+ sanitizers_cmd,
+ "-I%s" % libfuzzer_src_root,
+ extra_cmd
+ ])
config.substitutions.append(('%cpp_compiler',
generate_compiler_cmd(is_cpp=True, fuzzer_enabled=True)
@@ -77,3 +103,13 @@ config.substitutions.append(('%no_fuzzer_cpp_compiler',
config.substitutions.append(('%no_fuzzer_c_compiler',
generate_compiler_cmd(is_cpp=False, fuzzer_enabled=False)
))
+
+config.substitutions.append(('%msan_compiler',
+ generate_compiler_cmd(is_cpp=True, fuzzer_enabled=True, msan_enabled=True)
+ ))
+
+if config.host_os == 'Darwin':
+ if config.target_arch in ["x86_64", "x86_64h"]:
+ config.parallelism_group = "darwin-64bit-sanitizer"
+ elif config.apple_platform != "osx" and not config.apple_platform.endswith("sim"):
+ config.parallelism_group = "darwin-ios-device-sanitizer"
diff --git a/test/fuzzer/lit.site.cfg.in b/test/fuzzer/lit.site.cfg.in
index 7f70c8f67d69..b333c78e59e9 100644
--- a/test/fuzzer/lit.site.cfg.in
+++ b/test/fuzzer/lit.site.cfg.in
@@ -1,17 +1,24 @@
@LIT_SITE_CFG_IN_HEADER@
-config.test_exec_root = "@CMAKE_CURRENT_BINARY_DIR@"
-
config.cpp_compiler = "@LIBFUZZER_TEST_COMPILER@"
config.target_flags = "@LIBFUZZER_TEST_FLAGS@"
config.c_compiler = "@LIBFUZZER_TEST_COMPILER@"
+config.stdlib = "@LIBFUZZER_TEST_STDLIB@"
+config.apple_platform = "@LIBFUZZER_TEST_APPLE_PLATFORM@"
+config.name_suffix = "@LIBFUZZER_TEST_CONFIG_SUFFIX@"
config.osx_sysroot_flag = "@OSX_SYSROOT_FLAG@"
config.cmake_binary_dir = "@CMAKE_BINARY_DIR@"
+config.llvm_library_dir = "@LLVM_LIBRARY_DIR@"
config.target_triple = "@TARGET_TRIPLE@"
# Load common config for all compiler-rt lit tests.
lit_config.load_config(config,
"@COMPILER_RT_BINARY_DIR@/test/lit.common.configured")
+if config.enable_per_target_runtime_dir:
+ config.runtime_library_dir = config.compiler_rt_libdir
+else:
+ config.runtime_library_dir = "@LLVM_LIBRARY_DIR@"
+
lit_config.load_config(config, "@CMAKE_CURRENT_SOURCE_DIR@/lit.cfg")
diff --git a/test/fuzzer/max-number-of-runs.test b/test/fuzzer/max-number-of-runs.test
index efe7a9c0f629..c1fa93101510 100644
--- a/test/fuzzer/max-number-of-runs.test
+++ b/test/fuzzer/max-number-of-runs.test
@@ -1,10 +1,10 @@
RUN: %cpp_compiler %S/AccumulateAllocationsTest.cpp -o %t-AccumulateAllocationsTest
-RUN: %t-AccumulateAllocationsTest -seed=1 -runs=2 2>&1 | FileCheck %s --check-prefix=CHECK1
+RUN: %run %t-AccumulateAllocationsTest -seed=1 -runs=2 2>&1 | FileCheck %s --check-prefix=CHECK1
CHECK1: Done 2 runs
-RUN: %t-AccumulateAllocationsTest -seed=1 -runs=3 2>&1 | FileCheck %s --check-prefix=CHECK2
+RUN: %run %t-AccumulateAllocationsTest -seed=1 -runs=3 2>&1 | FileCheck %s --check-prefix=CHECK2
CHECK2: Done 3 runs
-RUN: %t-AccumulateAllocationsTest -seed=1 -runs=4 2>&1 | FileCheck %s --check-prefix=CHECK3
+RUN: %run %t-AccumulateAllocationsTest -seed=1 -runs=4 2>&1 | FileCheck %s --check-prefix=CHECK3
CHECK3: Done 4 runs
diff --git a/test/fuzzer/memcmp.test b/test/fuzzer/memcmp.test
index 3431a524ced5..5657cab41dfc 100644
--- a/test/fuzzer/memcmp.test
+++ b/test/fuzzer/memcmp.test
@@ -1,3 +1,4 @@
+UNSUPPORTED: freebsd
RUN: %cpp_compiler %S/MemcmpTest.cpp -o %t-MemcmpTest
-RUN: not %t-MemcmpTest -seed=1 -runs=10000000 2>&1 | FileCheck %s
+RUN: not %run %t-MemcmpTest -seed=1 -runs=10000000 2>&1 | FileCheck %s
CHECK: BINGO
diff --git a/test/fuzzer/memcmp64.test b/test/fuzzer/memcmp64.test
index 223c3bd42a7d..24d14bf73bbf 100644
--- a/test/fuzzer/memcmp64.test
+++ b/test/fuzzer/memcmp64.test
@@ -1,3 +1,4 @@
+UNSUPPORTED: freebsd
RUN: %cpp_compiler %S/Memcmp64BytesTest.cpp -o %t-Memcmp64BytesTest
-RUN: not %t-Memcmp64BytesTest -seed=1 -runs=1000000 2>&1 | FileCheck %s
+RUN: not %run %t-Memcmp64BytesTest -seed=1 -runs=1000000 2>&1 | FileCheck %s
CHECK: BINGO
diff --git a/test/fuzzer/merge-control-file.test b/test/fuzzer/merge-control-file.test
index 2da5c4ccfb2b..64b747116a9f 100644
--- a/test/fuzzer/merge-control-file.test
+++ b/test/fuzzer/merge-control-file.test
@@ -1,3 +1,4 @@
+XFAIL: ios
RUN: mkdir -p %t
RUN: %cpp_compiler %S/FullCoverageSetTest.cpp -o %t/T
@@ -10,9 +11,9 @@ RUN: echo ..Z... > %t/T0/3
# Test what happens if the control file is junk.
RUN: echo JUNK > %t/MCF
-RUN: not %t/T -merge=1 %t/T1 %t/T2 -merge_control_file=%t/MCF 2>&1 | FileCheck %s --check-prefix=JUNK
+RUN: not %run %t/T -merge=1 %t/T1 %t/T2 -merge_control_file=%t/MCF 2>&1 | FileCheck %s --check-prefix=JUNK
RUN: echo 3 > %t/MCF; echo 0 >> %t/MCF; echo %t/T1/1 >> %t/MCF
-RUN: not %t/T -merge=1 %t/T1 %t/T2 -merge_control_file=%t/MCF 2>&1 | FileCheck %s --check-prefix=JUNK
+RUN: not %run %t/T -merge=1 %t/T1 %t/T2 -merge_control_file=%t/MCF 2>&1 | FileCheck %s --check-prefix=JUNK
JUNK: MERGE-OUTER: non-empty control file provided: {{.*}}MCF
JUNK: MERGE-OUTER: bad control file, will overwrite it
@@ -21,18 +22,18 @@ JUNK: MERGE-OUTER: bad control file, will overwrite it
RUN: rm -f %t/T1/*; cp %t/T0/* %t/T1
RUN: echo 3 > %t/MCF; echo 0 >> %t/MCF; echo %t/T1/1 >> %t/MCF; echo %t/T1/2 >> %t/MCF; echo %t/T1/3 >> %t/MCF
-RUN: %t/T -merge=1 %t/T1 %t/T2 -merge_control_file=%t/MCF 2>&1 | FileCheck %s --check-prefix=OK_0
+RUN: %run %t/T -merge=1 %t/T1 %t/T2 -merge_control_file=%t/MCF 2>&1 | FileCheck %s --check-prefix=OK_0
OK_0: MERGE-OUTER: control file ok, 3 files total, first not processed file 0
OK_0: MERGE-OUTER: 3 new files with {{.*}} new features added
RUN: rm -f %t/T1/*; cp %t/T0/* %t/T1
RUN: echo 3 > %t/MCF; echo 0 >> %t/MCF; echo %t/T1/1 >> %t/MCF; echo %t/T1/2 >> %t/MCF; echo %t/T1/3 >> %t/MCF
-RUN: %t/T -merge=1 %t/T1 %t/T2 -merge_control_file=%t/MCF -save_coverage_summary=%t/SUMMARY 2>&1 | FileCheck %s --check-prefix=SAVE_SUMMARY
+RUN: %run %t/T -merge=1 %t/T1 %t/T2 -merge_control_file=%t/MCF -save_coverage_summary=%t/SUMMARY 2>&1 | FileCheck %s --check-prefix=SAVE_SUMMARY
SAVE_SUMMARY: MERGE-OUTER: writing coverage summary for 3 files to {{.*}}/SUMMARY
RUN: rm -f %t/T1/*; cp %t/T0/* %t/T1
RUN: echo 3 > %t/MCF; echo 0 >> %t/MCF; echo %t/T1/1 >> %t/MCF; echo %t/T1/2 >> %t/MCF; echo %t/T1/3 >> %t/MCF
-RUN: %t/T -merge=1 %t/T1 %t/T2 -merge_control_file=%t/MCF -load_coverage_summary=%t/SUMMARY 2>&1 | FileCheck %s --check-prefix=LOAD_SUMMARY
+RUN: %run %t/T -merge=1 %t/T1 %t/T2 -merge_control_file=%t/MCF -load_coverage_summary=%t/SUMMARY 2>&1 | FileCheck %s --check-prefix=LOAD_SUMMARY
LOAD_SUMMARY: MERGE-OUTER: coverage summary loaded from
RUN: rm -f %t/T1/*; cp %t/T0/* %t/T1
@@ -41,7 +42,7 @@ RUN: echo STARTED 0 1 >> %t/MCF
RUN: echo DONE 0 11 >> %t/MCF
RUN: echo STARTED 1 2 >> %t/MCF
RUN: echo DONE 1 12 >> %t/MCF
-RUN: %t/T -merge=1 %t/T1 %t/T2 -merge_control_file=%t/MCF 2>&1 | FileCheck %s --check-prefix=OK_2
+RUN: %run %t/T -merge=1 %t/T1 %t/T2 -merge_control_file=%t/MCF 2>&1 | FileCheck %s --check-prefix=OK_2
OK_2: MERGE-OUTER: control file ok, 3 files total, first not processed file 2
OK_2: MERGE-OUTER: 3 new files with {{.*}} new features added
@@ -53,5 +54,5 @@ RUN: echo STARTED 1 2 >> %t/MCF
RUN: echo DONE 1 12 >> %t/MCF
RUN: echo STARTED 2 2 >> %t/MCF
RUN: echo DONE 2 13 >> %t/MCF
-RUN: %t/T -merge=1 %t/T1 %t/T2 -merge_control_file=%t/MCF 2>&1 | FileCheck %s --check-prefix=OK_3
+RUN: %run %t/T -merge=1 %t/T1 %t/T2 -merge_control_file=%t/MCF 2>&1 | FileCheck %s --check-prefix=OK_3
OK_3: MERGE-OUTER: nothing to do, merge has been completed before
diff --git a/test/fuzzer/merge-posix.test b/test/fuzzer/merge-posix.test
index e34e3a325b74..db0a48b5481e 100644
--- a/test/fuzzer/merge-posix.test
+++ b/test/fuzzer/merge-posix.test
@@ -1,3 +1,4 @@
+XFAIL: ios
RUN: %cpp_compiler %S/FullCoverageSetTest.cpp -o %t-FullCoverageSetTest
RUN: rm -rf %tmp/T1 %tmp/T2
@@ -15,9 +16,9 @@ RUN: echo ....E. > %tmp/T2/5
RUN: echo .....R > %tmp/T2/6
# Check that we can report an error if file size exceeded
-RUN: (ulimit -f 1; not %t-FullCoverageSetTest -merge=1 %tmp/T1 %tmp/T2 2>&1 | FileCheck %s --check-prefix=SIGXFSZ)
+RUN: (ulimit -f 1; not %run %t-FullCoverageSetTest -merge=1 %tmp/T1 %tmp/T2 2>&1 | FileCheck %s --check-prefix=SIGXFSZ)
SIGXFSZ: ERROR: libFuzzer: file size exceeded
# Check that we honor TMPDIR
-RUN: TMPDIR=DIR_DOES_NOT_EXIST not %t-FullCoverageSetTest -merge=1 %tmp/T1 %tmp/T2 2>&1 | FileCheck %s --check-prefix=TMPDIR
+RUN: TMPDIR=DIR_DOES_NOT_EXIST not %run %t-FullCoverageSetTest -merge=1 %tmp/T1 %tmp/T2 2>&1 | FileCheck %s --check-prefix=TMPDIR
TMPDIR: MERGE-OUTER: failed to write to the control file: DIR_DOES_NOT_EXIST/libFuzzerTemp
diff --git a/test/fuzzer/merge-sigusr.test b/test/fuzzer/merge-sigusr.test
index efb00daa4643..a03e5440a8b8 100644
--- a/test/fuzzer/merge-sigusr.test
+++ b/test/fuzzer/merge-sigusr.test
@@ -1,4 +1,5 @@
# Check that libFuzzer honors SIGUSR1/SIGUSR2
+UNSUPPORTED: darwin
RUN: rm -rf %t
RUN: mkdir -p %t
RUN: %cpp_compiler %S/SleepOneSecondTest.cpp -o %t/LFSIGUSR
@@ -12,7 +13,7 @@ RUN: echo e > %t/C2/e
RUN: echo f > %t/C2/f
RUN: echo g > %t/C2/g
-RUN: %t/LFSIGUSR -merge=1 -merge_control_file=%t/MCF %t/C1 %t/C2 2> %t/log & export PID=$!
+RUN: %run %t/LFSIGUSR -merge=1 -merge_control_file=%t/MCF %t/C1 %t/C2 2> %t/log & export PID=$!
RUN: sleep 3
RUN: pkill -SIGUSR2 -f %t/LFSIGUSR
RUN: sleep 3
diff --git a/test/fuzzer/merge-summary.test b/test/fuzzer/merge-summary.test
index 3e21c23ef38d..116cf1db8755 100644
--- a/test/fuzzer/merge-summary.test
+++ b/test/fuzzer/merge-summary.test
@@ -9,9 +9,9 @@ RUN: echo F..... > %t/T2/a
RUN: echo .U.... > %t/T2/b
RUN: echo ..Z... > %t/T2/c
-RUN: %t-FullCoverageSetTest -merge=1 %t/T1 %t/T2 -save_coverage_summary=%t/SUMMARY 2>&1 | FileCheck %s --check-prefix=SAVE_SUMMARY
+RUN: %run %t-FullCoverageSetTest -merge=1 %t/T1 %t/T2 -save_coverage_summary=%t/SUMMARY 2>&1 | FileCheck %s --check-prefix=SAVE_SUMMARY
SAVE_SUMMARY: MERGE-OUTER: writing coverage summary for 6 files to {{.*}}SUMMARY
RUN: rm %t/T1/*
-RUN: %t-FullCoverageSetTest -merge=1 %t/T1 %t/T2 -load_coverage_summary=%t/SUMMARY 2>&1 | FileCheck %s --check-prefix=LOAD_SUMMARY
+RUN: %run %t-FullCoverageSetTest -merge=1 %t/T1 %t/T2 -load_coverage_summary=%t/SUMMARY 2>&1 | FileCheck %s --check-prefix=LOAD_SUMMARY
LOAD_SUMMARY: MERGE-OUTER: coverage summary loaded from {{.*}}SUMMAR
LOAD_SUMMARY: MERGE-OUTER: 0 new files with 0 new features added
diff --git a/test/fuzzer/merge.test b/test/fuzzer/merge.test
index d17405595eb7..ec41c82b9344 100644
--- a/test/fuzzer/merge.test
+++ b/test/fuzzer/merge.test
@@ -1,3 +1,4 @@
+XFAIL: ios
CHECK: BINGO
RUN: %cpp_compiler %S/FullCoverageSetTest.cpp -o %t-FullCoverageSetTest
@@ -10,7 +11,7 @@ RUN: echo ..Z... > %t/T0/3
# T1 has 3 elements, T2 is empty.
RUN: cp %t/T0/* %t/T1/
-RUN: %t-FullCoverageSetTest -merge=1 %t/T1 %t/T2 2>&1 | FileCheck %s --check-prefix=CHECK1
+RUN: %run %t-FullCoverageSetTest -merge=1 %t/T1 %t/T2 2>&1 | FileCheck %s --check-prefix=CHECK1
CHECK1: MERGE-OUTER: 3 files, 3 in the initial corpus
CHECK1: MERGE-OUTER: 0 new files with 0 new features added
@@ -22,12 +23,12 @@ RUN: echo .U.... > %t/T2/b
RUN: echo ..Z... > %t/T2/c
# T1 has 3 elements, T2 has 6 elements, only 3 are new.
-RUN: %t-FullCoverageSetTest -merge=1 %t/T1 %t/T2 2>&1 | FileCheck %s --check-prefix=CHECK2
+RUN: %run %t-FullCoverageSetTest -merge=1 %t/T1 %t/T2 2>&1 | FileCheck %s --check-prefix=CHECK2
CHECK2: MERGE-OUTER: 9 files, 3 in the initial corpus
CHECK2: MERGE-OUTER: 3 new files with 3 new features added
# Now, T1 has 6 units and T2 has no new interesting units.
-RUN: %t-FullCoverageSetTest -merge=1 %t/T1 %t/T2 2>&1 | FileCheck %s --check-prefix=CHECK3
+RUN: %run %t-FullCoverageSetTest -merge=1 %t/T1 %t/T2 2>&1 | FileCheck %s --check-prefix=CHECK3
CHECK3: MERGE-OUTER: 12 files, 6 in the initial corpus
CHECK3: MERGE-OUTER: 0 new files with 0 new features added
@@ -35,14 +36,14 @@ CHECK3: MERGE-OUTER: 0 new files with 0 new features added
RUN: rm %t/T1/*
RUN: cp %t/T0/* %t/T1/
RUN: echo looooooooong > %t/T2/looooooooong
-RUN: %t-FullCoverageSetTest -merge=1 %t/T1 %t/T2 -max_len=6 2>&1 | FileCheck %s --check-prefix=MAX_LEN
+RUN: %run %t-FullCoverageSetTest -merge=1 %t/T1 %t/T2 -max_len=6 2>&1 | FileCheck %s --check-prefix=MAX_LEN
MAX_LEN: MERGE-OUTER: 3 new files
# Check that we respect -merge_control_file=FILE
RUN: rm %t/T1/*
RUN: cp %t/T0/* %t/T1/
RUN: rm -f %t/MCF
-RUN: %t-FullCoverageSetTest -merge=1 -merge_control_file=%t/MCF %t/T1 %t/T2 2>&1 | FileCheck %s --check-prefix=MCF
+RUN: %run %t-FullCoverageSetTest -merge=1 -merge_control_file=%t/MCF %t/T1 %t/T2 2>&1 | FileCheck %s --check-prefix=MCF
RUN: grep STARTED %t/MCF
RUN: grep DONE %t/MCF
MCF: MERGE-INNER: using the control file {{.*}}MCF
@@ -53,18 +54,18 @@ MCF: MERGE-OUTER: 3 new files
RUN: rm %t/T1/*
RUN: cp %t/T0/* %t/T1/
RUN: echo 'FUZZER' > %t/T2/FUZZER
-RUN: %t-FullCoverageSetTest -merge=1 %t/T1 %t/T2 2>&1 | FileCheck %s --check-prefix=MERGE_WITH_CRASH
+RUN: %run %t-FullCoverageSetTest -merge=1 %t/T1 %t/T2 2>&1 | FileCheck %s --check-prefix=MERGE_WITH_CRASH
MERGE_WITH_CRASH: MERGE-OUTER: succesfull in 2 attempt(s)
MERGE_WITH_CRASH: MERGE-OUTER: 3 new files
# Check that we actually limit the size with max_len
RUN: rm %t/T1/* %t/T2/*
RUN: echo 'FUZZER' > %t/T2/FUZZER
-RUN: %t-FullCoverageSetTest -merge=1 %t/T1 %t/T2 -max_len=5 2>&1 | FileCheck %s --check-prefix=MERGE_LEN5
+RUN: %run %t-FullCoverageSetTest -merge=1 %t/T1 %t/T2 -max_len=5 2>&1 | FileCheck %s --check-prefix=MERGE_LEN5
RUN: not grep FUZZER %t/T1/*
RUN: grep FUZZE %t/T1/*
MERGE_LEN5: MERGE-OUTER: succesfull in 1 attempt(s)
RUN: rm -rf %t/T1/* %t/T2/*
-RUN: not %t-FullCoverageSetTest -merge=1 %t/T1 %t/T2 2>&1 | FileCheck %s --check-prefix=EMPTY
+RUN: not %run %t-FullCoverageSetTest -merge=1 %t/T1 %t/T2 2>&1 | FileCheck %s --check-prefix=EMPTY
EMPTY: MERGE-OUTER: zero succesfull attempts, exiting
diff --git a/test/fuzzer/minimize_crash.test b/test/fuzzer/minimize_crash.test
index 77ab370fa899..de44b8747e04 100644
--- a/test/fuzzer/minimize_crash.test
+++ b/test/fuzzer/minimize_crash.test
@@ -1,16 +1,17 @@
RUN: %cpp_compiler %S/NullDerefTest.cpp -o %t-NullDerefTest
RUN: %cpp_compiler %S/SingleByteInputTest.cpp -o %t-SingleByteInputTest
+RUN: mkdir -p %t.dir
-RUN: echo 'Hi!rv349f34t3gg' > not_minimal_crash
-RUN: %t-NullDerefTest -minimize_crash=1 not_minimal_crash -max_total_time=2 2>&1 | FileCheck %s
-CHECK: CRASH_MIN: failed to minimize beyond ./minimized-from-{{.*}} (3 bytes), exiting
-RUN: %t-NullDerefTest -minimize_crash=1 not_minimal_crash -max_total_time=2 -exact_artifact_path=exact_minimized_path 2>&1 | FileCheck %s --check-prefix=CHECK_EXACT
-CHECK_EXACT: CRASH_MIN: failed to minimize beyond exact_minimized_path (3 bytes), exiting
-RUN: rm not_minimal_crash minimized-from-* exact_minimized_path
+RUN: echo 'Hi!rv349f34t3gg' > %t.dir/not_minimal_crash
+RUN: %run %t-NullDerefTest -minimize_crash=1 %t.dir/not_minimal_crash -max_total_time=2 2>&1 | FileCheck %s
+CHECK: CRASH_MIN: failed to minimize beyond {{.*}}minimized-from{{.*}} (3 bytes), exiting
+RUN: %run %t-NullDerefTest -minimize_crash=1 %t.dir/not_minimal_crash -max_total_time=2 -exact_artifact_path=%t.exact_minimized_path 2>&1 | FileCheck %s --check-prefix=CHECK_EXACT
+CHECK_EXACT: CRASH_MIN: failed to minimize beyond {{.*}}exact_minimized_path{{.*}} (3 bytes), exiting
+RUN: rm %t.dir/not_minimal_crash %t.exact_minimized_path
-RUN: echo -n 'abcd*xyz' > not_minimal_crash
-RUN: %t-SingleByteInputTest -minimize_crash=1 not_minimal_crash -exact_artifact_path=exact_minimized_path 2>&1 | FileCheck %s --check-prefix=MIN1
-MIN1: Test unit written to exact_minimized_path
-MIN1: Test unit written to exact_minimized_path
+RUN: echo -n 'abcd*xyz' > %t.dir/not_minimal_crash
+RUN: %run %t-SingleByteInputTest -minimize_crash=1 %t.dir/not_minimal_crash -exact_artifact_path=%t.exact_minimized_path 2>&1 | FileCheck %s --check-prefix=MIN1
+MIN1: Test unit written to {{.*}}exact_minimized_path
+MIN1: Test unit written to {{.*}}exact_minimized_path
MIN1: INFO: The input is small enough, exiting
-MIN1: CRASH_MIN: failed to minimize beyond exact_minimized_path (1 bytes), exiting
+MIN1: CRASH_MIN: failed to minimize beyond {{.*}}exact_minimized_path (1 bytes), exiting
diff --git a/test/fuzzer/minimize_two_crashes.test b/test/fuzzer/minimize_two_crashes.test
index e6ff9990ffd8..3c528f707666 100644
--- a/test/fuzzer/minimize_two_crashes.test
+++ b/test/fuzzer/minimize_two_crashes.test
@@ -1,10 +1,12 @@
# Test that the minimizer stops when it sees a differe bug.
+UNSUPPORTED: freebsd
-RUN: %cpp_compiler %S/TwoDifferentBugsTest.cpp -o %t-TwoDifferentBugsTest
+# TODO: Find out why test fails on Darwin with -O2.
+RUN: %cpp_compiler -O0 %S/TwoDifferentBugsTest.cpp -o %t-TwoDifferentBugsTest
RUN: rm -rf %t && mkdir %t
RUN: echo H12345678901234667888090 > %t/long_crash
-RUN: env ASAN_OPTIONS=dedup_token_length=3 %t-TwoDifferentBugsTest -seed=1 -minimize_crash=1 %t/long_crash -exact_artifact_path=%t/result 2>&1 | FileCheck %s
+RUN: env ASAN_OPTIONS=dedup_token_length=3 %run %t-TwoDifferentBugsTest -seed=1 -minimize_crash=1 %t/long_crash -exact_artifact_path=%t/result 2>&1 | FileCheck %s
CHECK: DedupToken1: DEDUP_TOKEN: Bar
CHECK: DedupToken2: DEDUP_TOKEN: Bar
@@ -12,7 +14,7 @@ CHECK: DedupToken1: DEDUP_TOKEN: Bar
CHECK: DedupToken2: DEDUP_TOKEN: Foo
CHECK: CRASH_MIN: mismatch in dedup tokens
-RUN: not %t-TwoDifferentBugsTest %t/result 2>&1 | FileCheck %s --check-prefix=VERIFY
+RUN: not %run %t-TwoDifferentBugsTest %t/result 2>&1 | FileCheck %s --check-prefix=VERIFY
VERIFY: ERROR: AddressSanitizer:
VERIFY: in Bar
diff --git a/test/fuzzer/msan.test b/test/fuzzer/msan.test
new file mode 100644
index 000000000000..2e0339bb8ff7
--- /dev/null
+++ b/test/fuzzer/msan.test
@@ -0,0 +1,24 @@
+REQUIRES: msan
+RUN: %msan_compiler %S/SimpleTestStdio.cpp -o %t
+RUN: not %run %t -seed=1 -runs=10000000 2>&1 | FileCheck %s --check-prefix=NO-REPORT
+
+RUN: %msan_compiler %S/SimpleCmpTest.cpp -o %t
+RUN: not %run %t -seed=1 -runs=10000000 2>&1 | FileCheck %s --check-prefix=NO-REPORT
+
+RUN: %msan_compiler %S/MemcmpTest.cpp -o %t
+RUN: not %run %t -seed=1 -runs=10000000 2>&1 | FileCheck %s --check-prefix=NO-REPORT
+
+RUN: %msan_compiler %S/StrcmpTest.cpp -o %t
+RUN: not %run %t -seed=1 -runs=10000000 2>&1 | FileCheck %s --check-prefix=NO-REPORT
+
+NO-REPORT-NOT: MemorySanitizer
+NO-REPORT: BINGO
+
+
+RUN: %msan_compiler %S/UseAfterDtor.cpp -o %t
+RUN: MSAN_OPTIONS=poison_in_dtor=1 not %run %t -seed=1 -runs=10000000 2>&1 | FileCheck %s --check-prefix=REPORT
+
+RUN: %msan_compiler %S/UninitializedStrlen.cpp -o %t
+RUN: not %run %t -seed=1 -runs=10000000 2>&1 | FileCheck %s --check-prefix=REPORT
+
+REPORT: MemorySanitizer: use-of-uninitialized-value
diff --git a/test/fuzzer/not-instrumented.test b/test/fuzzer/not-instrumented.test
new file mode 100644
index 000000000000..2330c4770067
--- /dev/null
+++ b/test/fuzzer/not-instrumented.test
@@ -0,0 +1,4 @@
+RUN: %cpp_compiler %S/NotinstrumentedTest.cpp -fsanitize-coverage=0 -o %t-NotinstrumentedTest-NoCoverage
+RUN: not %run %t-NotinstrumentedTest-NoCoverage 2>&1 | FileCheck %s --check-prefix=NO_COVERAGE
+
+NO_COVERAGE: ERROR: no interesting inputs were found. Is the code instrumented for coverage? Exiting
diff --git a/test/fuzzer/null-deref-on-empty.test b/test/fuzzer/null-deref-on-empty.test
new file mode 100644
index 000000000000..f159a79f4838
--- /dev/null
+++ b/test/fuzzer/null-deref-on-empty.test
@@ -0,0 +1,4 @@
+RUN: %cpp_compiler %S/NullDerefOnEmptyTest.cpp -o %t-NullDerefOnEmptyTest
+
+RUN: not %run %t-NullDerefOnEmptyTest -print_final_stats=1 2>&1 | FileCheck %s --check-prefix=NULL_DEREF_ON_EMPTY
+NULL_DEREF_ON_EMPTY: stat::number_of_executed_units:
diff --git a/test/fuzzer/null-deref.test b/test/fuzzer/null-deref.test
new file mode 100644
index 000000000000..31eb5990da33
--- /dev/null
+++ b/test/fuzzer/null-deref.test
@@ -0,0 +1,10 @@
+RUN: %cpp_compiler %S/NullDerefTest.cpp -o %t-NullDerefTest
+
+RUN: not %run %t-NullDerefTest 2>&1 | FileCheck %s --check-prefix=NullDerefTest
+RUN: not %run %t-NullDerefTest -close_fd_mask=3 2>&1 | FileCheck %s --check-prefix=NullDerefTest
+NullDerefTest: ERROR: AddressSanitizer: {{SEGV|access-violation}} on unknown address
+NullDerefTest: Test unit written to ./crash-
+RUN: not %run %t-NullDerefTest -artifact_prefix=ZZZ 2>&1 | FileCheck %s --check-prefix=NullDerefTestPrefix
+NullDerefTestPrefix: Test unit written to ZZZcrash-
+RUN: not %run %t-NullDerefTest -artifact_prefix=ZZZ -exact_artifact_path=FOOBAR 2>&1 | FileCheck %s --check-prefix=NullDerefTestExactPath
+NullDerefTestExactPath: Test unit written to FOOBAR
diff --git a/test/fuzzer/only-some-bytes.test b/test/fuzzer/only-some-bytes.test
new file mode 100644
index 000000000000..fbfef14c7850
--- /dev/null
+++ b/test/fuzzer/only-some-bytes.test
@@ -0,0 +1,38 @@
+# Tests the data flow tracer.
+REQUIRES: linux
+UNSUPPORTED: aarch64
+
+# Build the tracer and the test.
+RUN: %no_fuzzer_cpp_compiler -c -fno-sanitize=all -fsanitize=dataflow %S/../../lib/fuzzer/dataflow/DataFlow.cpp -o %t-DataFlow.o
+RUN: %no_fuzzer_cpp_compiler -fno-sanitize=all -fsanitize=dataflow -fsanitize-coverage=trace-pc-guard,pc-table,func,trace-cmp %S/OnlySomeBytesTest.cpp %t-DataFlow.o -o %t-DFT
+RUN: %cpp_compiler %S/OnlySomeBytesTest.cpp -o %t-Fuzz
+
+# Prepare the inputs.
+RUN: rm -rf %t/*
+RUN: mkdir -p %t/IN
+RUN: echo -n 0123456789012345678901234567890123456789012345678901234567891234 > %t/IN/6
+RUN: cat %t/IN/6 %t/IN/6 %t/IN/6 %t/IN/6 > %t/IN/8
+RUN: cat %t/IN/8 %t/IN/8 %t/IN/8 %t/IN/8 > %t/IN/10
+RUN: cat %t/IN/10 %t/IN/10 %t/IN/10 %t/IN/10 > %t/IN/12
+# %t/IN/12 is 4096 bytes-long.
+
+RUN: %t-Fuzz -focus_function=f0 -runs=0 %t/IN 2>&1 | FileCheck %s --check-prefix=NO_FOCUSED_INPUT
+NO_FOCUSED_INPUT: INFO: 0/2 inputs touch the focus function
+
+RUN: (echo -n ABC; cat %t/IN/12) > %t/IN/ABC
+RUN: %t-Fuzz -focus_function=f0 -runs=0 %t/IN 2>&1 | FileCheck %s --check-prefix=ONE_FOCUSED_INPUT
+ONE_FOCUSED_INPUT: INFO: 1/3 inputs touch the focus function
+
+RUN: rm -rf %t/IN_DFT
+RUN: %libfuzzer_src/scripts/collect_data_flow.py %t-DFT %t/IN %t/IN_DFT > /dev/null 2>&1
+
+# Repeat twice to make sure that the inputs with DFT are not removed from the corpus.
+RUN: %t-Fuzz -focus_function=f0 -data_flow_trace=%t/IN_DFT -runs=100 %t/IN 2>&1 | FileCheck %s --check-prefix=HAVE_DFT
+RUN: %t-Fuzz -focus_function=f0 -data_flow_trace=%t/IN_DFT -runs=100 %t/IN 2>&1 | FileCheck %s --check-prefix=HAVE_DFT
+HAVE_DFT: INFO: 1/{{.*}} inputs have the Data Flow Trace
+
+# Collect DFT, then use it.
+RUN: rm -rf %t/C && mkdir %t/C && cp %t/IN/* %t/C
+RUN: rm -rf %t/C_DFT && %libfuzzer_src/scripts/collect_data_flow.py %t-DFT %t/C %t/C_DFT > /dev/null 2>&1
+RUN: not %t-Fuzz -focus_function=f0 -data_flow_trace=%t/C_DFT -seed=1 -runs=1000000 -use_value_profile=3 %t/C 2> %t/log
+RUN: grep BINGO %t/log
diff --git a/test/fuzzer/overwrite-input.test b/test/fuzzer/overwrite-input.test
index 3695622d0352..e5ddd62cbdc7 100644
--- a/test/fuzzer/overwrite-input.test
+++ b/test/fuzzer/overwrite-input.test
@@ -1,3 +1,3 @@
RUN: %cpp_compiler %S/OverwriteInputTest.cpp -o %t-OverwriteInputTest
-RUN: not %t-OverwriteInputTest 2>&1 | FileCheck %s
+RUN: not %run %t-OverwriteInputTest 2>&1 | FileCheck %s
CHECK: ERROR: libFuzzer: fuzz target overwrites it's const input
diff --git a/test/fuzzer/print-func.test b/test/fuzzer/print-func.test
index 930e9992a2f9..c74da218282e 100644
--- a/test/fuzzer/print-func.test
+++ b/test/fuzzer/print-func.test
@@ -1,6 +1,7 @@
+UNSUPPORTED: darwin, aarch64
RUN: %cpp_compiler %S/PrintFuncTest.cpp -o %t
-RUN: %t -seed=1 -runs=100000 2>&1 | FileCheck %s
-RUN: %t -seed=1 -runs=100000 -print_funcs=0 2>&1 | FileCheck %s --check-prefix=NO
+RUN: %run %t -seed=1 -runs=100000 2>&1 | FileCheck %s
+RUN: %run %t -seed=1 -runs=100000 -print_funcs=0 2>&1 | FileCheck %s --check-prefix=NO
CHECK: NEW_FUNC{{.*}} FunctionA
CHECK: NEW_FUNC{{.*}} FunctionB
CHECK: NEW_FUNC{{.*}} FunctionC
diff --git a/test/fuzzer/print_unstable_stats.test b/test/fuzzer/print_unstable_stats.test
new file mode 100644
index 000000000000..bba99aecc838
--- /dev/null
+++ b/test/fuzzer/print_unstable_stats.test
@@ -0,0 +1,3 @@
+RUN: %cpp_compiler %S/PrintUnstableStatsTest.cpp -o %t-PrintUnstableStatsTest
+RUN: %run %t-PrintUnstableStatsTest -print_unstable_stats=1 -runs=100000 2>&1 | FileCheck %s --check-prefix=LONG
+LONG: stat::stability_rate: 27.59
diff --git a/test/fuzzer/recommended-dictionary.test b/test/fuzzer/recommended-dictionary.test
index 41b62c924ceb..e1d58c96fa20 100644
--- a/test/fuzzer/recommended-dictionary.test
+++ b/test/fuzzer/recommended-dictionary.test
@@ -1,5 +1,6 @@
+UNSUPPORTED: freebsd
RUN: %cpp_compiler %S/RepeatedMemcmp.cpp -o %t-RepeatedMemcmp
-RUN: %t-RepeatedMemcmp -seed=11 -runs=100000 -max_len=20 2>&1 | FileCheck %s --check-prefix=RECOMMENDED_DICT
+RUN: %run %t-RepeatedMemcmp -seed=11 -runs=100000 -max_len=20 2>&1 | FileCheck %s --check-prefix=RECOMMENDED_DICT
RECOMMENDED_DICT:###### Recommended dictionary. ######
RECOMMENDED_DICT-DAG: "foo"
RECOMMENDED_DICT-DAG: "bar"
diff --git a/test/fuzzer/reduce_inputs.test b/test/fuzzer/reduce_inputs.test
index 94f8cc4f37a8..e65f57227729 100644
--- a/test/fuzzer/reduce_inputs.test
+++ b/test/fuzzer/reduce_inputs.test
@@ -4,13 +4,13 @@ RUN: rm -rf %t/C
RUN: mkdir -p %t/C
RUN: %cpp_compiler %S/ShrinkControlFlowSimpleTest.cpp -o %t-ShrinkControlFlowSimpleTest
RUN: %cpp_compiler %S/ShrinkControlFlowTest.cpp -o %t-ShrinkControlFlowTest
-RUN: %t-ShrinkControlFlowSimpleTest -exit_on_item=0eb8e4ed029b774d80f2b66408203801cb982a60 -runs=1000000 %t/C 2>&1 | FileCheck %s
+RUN: %run %t-ShrinkControlFlowSimpleTest -exit_on_item=0eb8e4ed029b774d80f2b66408203801cb982a60 -runs=1000000 %t/C 2>&1 | FileCheck %s
CHECK: INFO: found item with checksum '0eb8e4ed029b774d80f2b66408203801cb982a60'
# Test that reduce_inputs deletes redundant files in the corpus.
-RUN: %t-ShrinkControlFlowSimpleTest -runs=0 %t/C 2>&1 | FileCheck %s --check-prefix=COUNT
+RUN: %run %t-ShrinkControlFlowSimpleTest -runs=0 %t/C 2>&1 | FileCheck %s --check-prefix=COUNT
COUNT: seed corpus: files: 4
# a bit longer test
-RUN: %t-ShrinkControlFlowTest -exit_on_item=0eb8e4ed029b774d80f2b66408203801cb982a60 -seed=1 -runs=1000000 2>&1 | FileCheck %s
+RUN: %run %t-ShrinkControlFlowTest -exit_on_item=0eb8e4ed029b774d80f2b66408203801cb982a60 -seed=42 -runs=1000000 2>&1 | FileCheck %s
diff --git a/test/fuzzer/repeated-bytes.test b/test/fuzzer/repeated-bytes.test
index 0bba2a91688f..e749a3e239a4 100644
--- a/test/fuzzer/repeated-bytes.test
+++ b/test/fuzzer/repeated-bytes.test
@@ -1,3 +1,3 @@
RUN: %cpp_compiler %S/RepeatedBytesTest.cpp -o %t-RepeatedBytesTest
CHECK: BINGO
-RUN: not %t-RepeatedBytesTest -seed=1 -runs=1000000 2>&1 | FileCheck %s
+RUN: not %run %t-RepeatedBytesTest -seed=1 -runs=1000000 2>&1 | FileCheck %s
diff --git a/test/fuzzer/shrink.test b/test/fuzzer/shrink.test
index 2988d4bbb043..5abbcc90b8c0 100644
--- a/test/fuzzer/shrink.test
+++ b/test/fuzzer/shrink.test
@@ -1,9 +1,9 @@
RUN: %cpp_compiler %S/ShrinkControlFlowTest.cpp -o %t-ShrinkControlFlowTest
RUN: %cpp_compiler %S/ShrinkValueProfileTest.cpp -o %t-ShrinkValueProfileTest
-RUN: %t-ShrinkControlFlowTest -seed=1 -exit_on_item=0eb8e4ed029b774d80f2b66408203801cb982a60 -runs=1000000 -shrink=1 -reduce_inputs=0 2>&1 | FileCheck %s --check-prefix=SHRINK1
+RUN: %run %t-ShrinkControlFlowTest -seed=1 -exit_on_item=0eb8e4ed029b774d80f2b66408203801cb982a60 -runs=1000000 -shrink=1 -reduce_inputs=0 2>&1 | FileCheck %s --check-prefix=SHRINK1
# Limit max_len to run this negative test faster.
-RUN: %t-ShrinkControlFlowTest -seed=1 -exit_on_item=0eb8e4ed029b774d80f2b66408203801cb982a60 -runs=1000000 -shrink=0 -reduce_inputs=0 -max_len=64 2>&1 | FileCheck %s --check-prefix=SHRINK0
-RUN: %t-ShrinkValueProfileTest -seed=1 -exit_on_item=aea2e3923af219a8956f626558ef32f30a914ebc -runs=100000 -shrink=1 -reduce_inputs=0 -use_value_profile=1 2>&1 | FileCheck %s --check-prefix=SHRINK1_VP
+RUN: %run %t-ShrinkControlFlowTest -seed=1 -exit_on_item=0eb8e4ed029b774d80f2b66408203801cb982a60 -runs=1000000 -shrink=0 -reduce_inputs=0 -max_len=64 2>&1 | FileCheck %s --check-prefix=SHRINK0
+RUN: %run %t-ShrinkValueProfileTest -seed=1 -exit_on_item=aea2e3923af219a8956f626558ef32f30a914ebc -runs=100000 -shrink=1 -reduce_inputs=0 -use_value_profile=1 2>&1 | FileCheck %s --check-prefix=SHRINK1_VP
SHRINK0: Done 1000000 runs in
SHRINK1: INFO: found item with checksum '0eb8e4ed029b774d80f2b66408203801cb982a60', exiting.
diff --git a/test/fuzzer/sigusr.test b/test/fuzzer/sigusr.test
index 12e3ac996c6c..0b3ddc72832d 100644
--- a/test/fuzzer/sigusr.test
+++ b/test/fuzzer/sigusr.test
@@ -1,9 +1,10 @@
+UNSUPPORTED: darwin
# Check that libFuzzer honors SIGUSR1/SIGUSR2
RUN: rm -rf %t
RUN: mkdir -p %t
RUN: %cpp_compiler %S/SleepOneSecondTest.cpp -o %t/LFSIGUSR
-RUN: %t/LFSIGUSR 2> %t/log & export PID=$!
+RUN: %run %t/LFSIGUSR 2> %t/log & export PID=$!
RUN: sleep 2
RUN: kill -SIGUSR1 $PID
RUN: sleep 3
diff --git a/test/fuzzer/simple-cmp.test b/test/fuzzer/simple-cmp.test
index 08123ed3ac47..e146379b2a5b 100644
--- a/test/fuzzer/simple-cmp.test
+++ b/test/fuzzer/simple-cmp.test
@@ -1,3 +1,7 @@
RUN: %cpp_compiler %S/SimpleCmpTest.cpp -o %t-SimpleCmpTest
+
+RUN: not %run %t-SimpleCmpTest -seed=1 -runs=100000000 2>&1 | FileCheck %s
+RUN: %run %t-SimpleCmpTest -max_total_time=1 -use_cmp=0 2>&1 | FileCheck %s --check-prefix=MaxTotalTime
+MaxTotalTime: Done {{.*}} runs in {{.}} second(s)
+
CHECK: BINGO
-RUN: not %t-SimpleCmpTest -seed=1 -runs=100000000 2>&1 | FileCheck %s
diff --git a/test/fuzzer/simple.test b/test/fuzzer/simple.test
new file mode 100644
index 000000000000..97a09be7cec9
--- /dev/null
+++ b/test/fuzzer/simple.test
@@ -0,0 +1,7 @@
+CHECK: BINGO
+RUN: %cpp_compiler %S/SimpleTest.cpp -o %t-SimpleTest
+
+RUN: not %run %t-SimpleTest 2>&1 | FileCheck %s
+
+# only_ascii mode. Will perform some minimal self-validation.
+RUN: not %run %t-SimpleTest -only_ascii=1 2>&1
diff --git a/test/fuzzer/standalone.test b/test/fuzzer/standalone.test
index e6483703f966..cd2422e4e683 100644
--- a/test/fuzzer/standalone.test
+++ b/test/fuzzer/standalone.test
@@ -2,7 +2,7 @@ RUN: %no_fuzzer_c_compiler %libfuzzer_src/standalone/StandaloneFuzzTargetMain.c
RUN: %no_fuzzer_cpp_compiler %S/InitializeTest.cpp -c -o %t_2.o
RUN: %no_fuzzer_cpp_compiler %t_1.o %t_2.o -o %t-StandaloneInitializeTest
-RUN: %t-StandaloneInitializeTest %S/hi.txt %S/dict1.txt 2>&1 | FileCheck %s
+RUN: %run %t-StandaloneInitializeTest %S/hi.txt %S/dict1.txt 2>&1 | FileCheck %s
CHECK: StandaloneFuzzTargetMain: running 2 inputs
CHECK: Done: {{.*}}hi.txt: (3 bytes)
CHECK: Done: {{.*}}dict1.txt: (61 bytes)
diff --git a/test/fuzzer/strcmp.test b/test/fuzzer/strcmp.test
index 47ad8f9ba0f5..bd917bba6b69 100644
--- a/test/fuzzer/strcmp.test
+++ b/test/fuzzer/strcmp.test
@@ -1,4 +1,5 @@
+UNSUPPORTED: freebsd
RUN: %cpp_compiler %S/StrcmpTest.cpp -o %t-StrcmpTest
-RUN: not %t-StrcmpTest -seed=1 -runs=2000000 2>&1 | FileCheck %s
+RUN: not %run %t-StrcmpTest -seed=1 -runs=2000000 2>&1 | FileCheck %s
CHECK: BINGO
diff --git a/test/fuzzer/strncmp-oob.test b/test/fuzzer/strncmp-oob.test
new file mode 100644
index 000000000000..a0365d961833
--- /dev/null
+++ b/test/fuzzer/strncmp-oob.test
@@ -0,0 +1,6 @@
+RUN: %cpp_compiler %S/StrncmpOOBTest.cpp -o %t-StrncmpOOBTest
+
+RUN: env ASAN_OPTIONS=strict_string_checks=1 not %run %t-StrncmpOOBTest -seed=1 -runs=1000000 2>&1 | FileCheck %s --check-prefix=STRNCMP
+STRNCMP: AddressSanitizer: heap-buffer-overflow
+STRNCMP-NOT: __sanitizer_weak_hook_strncmp
+STRNCMP: in LLVMFuzzerTestOneInput
diff --git a/test/fuzzer/strncmp.test b/test/fuzzer/strncmp.test
index 49693c8de8f0..50189445b102 100644
--- a/test/fuzzer/strncmp.test
+++ b/test/fuzzer/strncmp.test
@@ -1,4 +1,5 @@
+UNSUPPORTED: freebsd
RUN: %cpp_compiler %S/StrncmpTest.cpp -o %t-StrncmpTest
-RUN: not %t-StrncmpTest -seed=2 -runs=10000000 2>&1 | FileCheck %s
+RUN: not %run %t-StrncmpTest -seed=2 -runs=10000000 2>&1 | FileCheck %s
CHECK: BINGO
diff --git a/test/fuzzer/strstr.test b/test/fuzzer/strstr.test
index c39d5801acdb..f1fb210b47c7 100644
--- a/test/fuzzer/strstr.test
+++ b/test/fuzzer/strstr.test
@@ -1,4 +1,5 @@
+UNSUPPORTED: freebsd
RUN: %cpp_compiler %S/StrstrTest.cpp -o %t-StrstrTest
-RUN: not %t-StrstrTest -seed=1 -runs=2000000 2>&1 | FileCheck %s
+RUN: not %run %t-StrstrTest -seed=1 -runs=2000000 2>&1 | FileCheck %s
CHECK: BINGO
diff --git a/test/fuzzer/swap-cmp.test b/test/fuzzer/swap-cmp.test
index 5c2379cde4f6..7f7e2f60fa63 100644
--- a/test/fuzzer/swap-cmp.test
+++ b/test/fuzzer/swap-cmp.test
@@ -1,3 +1,3 @@
RUN: %cpp_compiler %S/SwapCmpTest.cpp -o %t-SwapCmpTest
CHECK: BINGO
-RUN: not %t-SwapCmpTest -seed=1 -runs=10000000 2>&1 | FileCheck %s
+RUN: not %run %t-SwapCmpTest -seed=1 -runs=10000000 2>&1 | FileCheck %s
diff --git a/test/fuzzer/symbolize-deadlock.test b/test/fuzzer/symbolize-deadlock.test
new file mode 100644
index 000000000000..25b519fd3fed
--- /dev/null
+++ b/test/fuzzer/symbolize-deadlock.test
@@ -0,0 +1,2 @@
+RUN: %cpp_compiler %S/SymbolizeDeadlock.cpp -o %t
+RUN: not %run %t -rss_limit_mb=20 2>&1
diff --git a/test/fuzzer/target-function.test b/test/fuzzer/target-function.test
new file mode 100644
index 000000000000..afd29ab8a83f
--- /dev/null
+++ b/test/fuzzer/target-function.test
@@ -0,0 +1,30 @@
+# Tests -focus_function
+#
+# TODO: don't require linux.
+# REQUIRES: linux
+UNSUPPORTED: aarch64
+
+RUN: %cpp_compiler %S/OnlySomeBytesTest.cpp -o %t-exe
+
+RUN: %t-exe -runs=100 2>&1 | FileCheck %s --check-prefix=FOCUS_NONE
+FOCUS_NONE-NOT: INFO: Focus function is set to
+FOCUS_NONE-NOT: INFO: {{.*}} inputs touch the focus function
+
+RUN: %t-exe -runs=100 -focus_function=WRONG 2>&1 | FileCheck %s --check-prefix=FOCUS_WRONG
+FOCUS_WRONG-NOT: INFO: Focus function is set to
+FOCUS_WRONG: INFO: 0/1 inputs touch the focus function
+
+RUN: %t-exe -runs=100 -focus_function=f0 2>&1 | FileCheck %s --check-prefix=FOCUS_F0
+FOCUS_F0: INFO: Focus function is set to 'f0'
+FOCUS_F0: INFO: 0/1 inputs touch the focus function
+
+RUN: rm -rf %t-corpus
+RUN: mkdir %t-corpus
+# ABC triggers the focus function, others don't.
+RUN: echo ABC$(for((i=0;i<2048;i++)); do echo -n x; done) > %t-corpus/ABC
+RUN: echo AXY$(for((i=0;i<2048;i++)); do echo -n x; done) > %t-corpus/AXY
+RUN: echo ABX$(for((i=0;i<2048;i++)); do echo -n x; done) > %t-corpus/ABX
+
+RUN: %t-exe -runs=10000 -focus_function=f0 %t-corpus 2>&1 | FileCheck %s --check-prefix=CORPUS_1_3
+CORPUS_1_3: INFO: 1/3 inputs touch the focus function
+CORPUS_1_3: DONE {{.*}} focus:
diff --git a/test/fuzzer/three-bytes.test b/test/fuzzer/three-bytes.test
new file mode 100644
index 000000000000..0b2187552cf5
--- /dev/null
+++ b/test/fuzzer/three-bytes.test
@@ -0,0 +1,8 @@
+Tests -use_value_profile=2 (alternative VP metric).
+RUN: %cpp_compiler %S/ThreeBytes.cpp -o %t
+
+RUN: %run %t -seed=1 -runs=30000
+RUN: %run %t -seed=1 -runs=30000 -use_value_profile=1
+RUN: not %run %t -seed=1 -runs=1000000 -use_value_profile=2 2>&1 | FileCheck %s
+
+CHECK: Test unit written
diff --git a/test/fuzzer/trace-malloc-2.test b/test/fuzzer/trace-malloc-2.test
index 56f16d786012..2b32b95ed3e6 100644
--- a/test/fuzzer/trace-malloc-2.test
+++ b/test/fuzzer/trace-malloc-2.test
@@ -4,7 +4,7 @@ UNSUPPORTED: darwin
RUN: %cpp_compiler %S/TraceMallocTest.cpp -o %t-TraceMallocTest
-RUN: %t-TraceMallocTest -seed=1 -trace_malloc=2 -runs=1000 2>&1 | FileCheck %s --check-prefix=TRACE2
+RUN: %run %t-TraceMallocTest -seed=1 -trace_malloc=2 -runs=1000 2>&1 | FileCheck %s --check-prefix=TRACE2
TRACE2-DAG: FREE[0]
TRACE2-DAG: MALLOC[0]
TRACE2-DAG: in LLVMFuzzerTestOneInput
diff --git a/test/fuzzer/trace-malloc-threaded.test b/test/fuzzer/trace-malloc-threaded.test
index 11f3f049155f..8f972d61f5c6 100644
--- a/test/fuzzer/trace-malloc-threaded.test
+++ b/test/fuzzer/trace-malloc-threaded.test
@@ -1,10 +1,11 @@
// FIXME: This test infinite loops on darwin because it crashes
// printing a stack trace repeatedly
-UNSUPPORTED: darwin
+UNSUPPORTED: darwin, aarch64
-RUN: %cpp_compiler %S/TraceMallocThreadedTest.cpp -o %t-TraceMallocThreadedTest
+RUN: %cpp_compiler %S/TraceMallocThreadedTest.cpp -o \
+RUN: %t-TraceMallocThreadedTest
-RUN: %t-TraceMallocThreadedTest -trace_malloc=2 -runs=1 2>&1 | FileCheck %s
+RUN: %run %t-TraceMallocThreadedTest -trace_malloc=2 -runs=1 2>&1 | FileCheck %s
CHECK: {{MALLOC\[[0-9]+] +0x[0-9]+ 5639}}
CHECK-NEXT: {{ +\#0 +}}
CHECK-NEXT: {{ +\#1 +}}
diff --git a/test/fuzzer/trace-malloc-unbalanced.test b/test/fuzzer/trace-malloc-unbalanced.test
index 8be5fab0ca43..193df01ddeff 100644
--- a/test/fuzzer/trace-malloc-unbalanced.test
+++ b/test/fuzzer/trace-malloc-unbalanced.test
@@ -6,10 +6,10 @@ UNSUPPORTED: darwin
RUN: %cpp_compiler %S/TraceMallocTest.cpp -o %t-TraceMallocTest
-RUN: %t-TraceMallocTest -seed=1 -trace_malloc=1 -runs=200 2>&1 | \
+RUN: %run %t-TraceMallocTest -seed=1 -trace_malloc=1 -runs=200 2>&1 | \
RUN: %libfuzzer_src/scripts/unbalanced_allocs.py --skip=5 | FileCheck %s
-RUN: %t-TraceMallocTest -seed=1 -trace_malloc=2 -runs=200 2>&1 | \
+RUN: %run %t-TraceMallocTest -seed=1 -trace_malloc=2 -runs=200 2>&1 | \
RUN: %libfuzzer_src/scripts/unbalanced_allocs.py --skip=5 | FileCheck %s --check-prefixes=CHECK,CHECK2
CHECK: MallocFreeTracer: START
diff --git a/test/fuzzer/trace-malloc.test b/test/fuzzer/trace-malloc.test
index 979be99b7ac2..156d06a0c01e 100644
--- a/test/fuzzer/trace-malloc.test
+++ b/test/fuzzer/trace-malloc.test
@@ -1,6 +1,6 @@
RUN: %cpp_compiler %S/TraceMallocTest.cpp -o %t-TraceMallocTest
-RUN: %t-TraceMallocTest -seed=1 -trace_malloc=1 -runs=10000 2>&1 | FileCheck %s
+RUN: %run %t-TraceMallocTest -seed=1 -trace_malloc=1 -runs=10000 2>&1 | FileCheck %s
CHECK-DAG: MallocFreeTracer: STOP 0 0 (same)
CHECK-DAG: MallocFreeTracer: STOP 0 1 (DIFFERENT)
CHECK-DAG: MallocFreeTracer: STOP 1 0 (DIFFERENT)
diff --git a/test/fuzzer/trace-pc.test b/test/fuzzer/trace-pc.test
index eaa0cb08afbe..30049331e360 100644
--- a/test/fuzzer/trace-pc.test
+++ b/test/fuzzer/trace-pc.test
@@ -1,3 +1,3 @@
-RUN: %cpp_compiler %S/SimpleTest.cpp -fno-sanitize-coverage=edge,trace-cmp,indirect-calls,8bit-counters,trace-pc-guard -fsanitize-coverage=trace-pc -o %t-SimpleTest-TracePC
+RUN: %cpp_compiler %S/SimpleTest.cpp -fsanitize-coverage=0 -fsanitize-coverage=trace-pc -o %t-SimpleTest-TracePC
CHECK: BINGO
-RUN: not %t-SimpleTest-TracePC -runs=1000000 -seed=1 2>&1 | FileCheck %s
+RUN: not %run %t-SimpleTest-TracePC -runs=1000000 -seed=1 2>&1 | FileCheck %s
diff --git a/test/fuzzer/ulimit.test b/test/fuzzer/ulimit.test
index 8772caa2d4c3..076866c50940 100644
--- a/test/fuzzer/ulimit.test
+++ b/test/fuzzer/ulimit.test
@@ -1,3 +1,3 @@
RUN: %cpp_compiler %S/SimpleTest.cpp -o %t-SimpleTest
RUN: ulimit -s 1000
-RUN: not %t-SimpleTest
+RUN: not %run %t-SimpleTest
diff --git a/test/fuzzer/value-profile-cmp.test b/test/fuzzer/value-profile-cmp.test
index 64244297c64a..b927422d10ff 100644
--- a/test/fuzzer/value-profile-cmp.test
+++ b/test/fuzzer/value-profile-cmp.test
@@ -1,3 +1,3 @@
CHECK: BINGO
RUN: %cpp_compiler %S/SimpleCmpTest.cpp -o %t-SimpleCmpTest
-RUN: not %t-SimpleCmpTest -seed=1 -use_cmp=0 -use_value_profile=1 -runs=100000000 2>&1 | FileCheck %s
+RUN: not %run %t-SimpleCmpTest -seed=1 -use_cmp=0 -use_value_profile=1 -runs=100000000 2>&1 | FileCheck %s
diff --git a/test/fuzzer/value-profile-cmp2.test b/test/fuzzer/value-profile-cmp2.test
index a585c9317fab..4bf119fcb3df 100644
--- a/test/fuzzer/value-profile-cmp2.test
+++ b/test/fuzzer/value-profile-cmp2.test
@@ -1,3 +1,3 @@
CHECK: BINGO
RUN: %cpp_compiler -fno-sanitize=address %S/SimpleHashTest.cpp -o %t-SimpleHashTest
-RUN: not %t-SimpleHashTest -seed=1 -use_cmp=0 -use_value_profile=1 -runs=100000000 -max_len=64 2>&1 | FileCheck %s
+RUN: not %run %t-SimpleHashTest -seed=1 -use_cmp=0 -use_value_profile=1 -runs=100000000 -max_len=64 2>&1 | FileCheck %s
diff --git a/test/fuzzer/value-profile-cmp3.test b/test/fuzzer/value-profile-cmp3.test
index d2284750b51e..58ba18b9001e 100644
--- a/test/fuzzer/value-profile-cmp3.test
+++ b/test/fuzzer/value-profile-cmp3.test
@@ -1,3 +1,3 @@
CHECK: BINGO
RUN: %cpp_compiler %S/AbsNegAndConstantTest.cpp -o %t-AbsNegAndConstantTest
-RUN: not %t-AbsNegAndConstantTest -seed=1 -use_cmp=0 -use_value_profile=1 -runs=100000000 2>&1 | FileCheck %s
+RUN: not %run %t-AbsNegAndConstantTest -seed=1 -use_cmp=0 -use_value_profile=1 -runs=100000000 2>&1 | FileCheck %s
diff --git a/test/fuzzer/value-profile-cmp4.test b/test/fuzzer/value-profile-cmp4.test
index bcbc67b1801f..05bc3f435912 100644
--- a/test/fuzzer/value-profile-cmp4.test
+++ b/test/fuzzer/value-profile-cmp4.test
@@ -1,3 +1,3 @@
CHECK: BINGO
RUN: %cpp_compiler %S/AbsNegAndConstant64Test.cpp -o %t-AbsNegAndConstant64Test
-RUN: not %t-AbsNegAndConstant64Test -seed=1 -use_cmp=0 -use_value_profile=1 -runs=100000000 2>&1 | FileCheck %s
+RUN: not %run %t-AbsNegAndConstant64Test -seed=1 -use_cmp=0 -use_value_profile=1 -runs=100000000 2>&1 | FileCheck %s
diff --git a/test/fuzzer/value-profile-div.test b/test/fuzzer/value-profile-div.test
index 8711a25466e5..59cc7c2f9552 100644
--- a/test/fuzzer/value-profile-div.test
+++ b/test/fuzzer/value-profile-div.test
@@ -1,4 +1,6 @@
+XFAIL: ios
+UNSUPPORTED: aarch64
CHECK: AddressSanitizer: {{FPE|int-divide-by-zero}}
RUN: %cpp_compiler %S/DivTest.cpp -fsanitize-coverage=trace-div -o %t-DivTest
-RUN: not %t-DivTest -seed=1 -use_value_profile=1 -runs=10000000 2>&1 | FileCheck %s
+RUN: not %run %t-DivTest -seed=1 -use_value_profile=1 -runs=10000000 2>&1 | FileCheck %s
diff --git a/test/fuzzer/value-profile-load.test b/test/fuzzer/value-profile-load.test
index 3bf2a658a5b2..607b81cd527f 100644
--- a/test/fuzzer/value-profile-load.test
+++ b/test/fuzzer/value-profile-load.test
@@ -1,3 +1,3 @@
CHECK: AddressSanitizer: global-buffer-overflow
-RUN: %cpp_compiler %S/LoadTest.cpp -fsanitize-coverage=trace-pc-guard,indirect-calls,trace-gep,trace-div,trace-cmp -o %t-LoadTest
-RUN: not %t-LoadTest -seed=2 -use_cmp=0 -use_value_profile=1 -runs=20000000 2>&1 | FileCheck %s
+RUN: %cpp_compiler %S/LoadTest.cpp -fsanitize-coverage=trace-gep -o %t-LoadTest
+RUN: not %run %t-LoadTest -seed=2 -use_cmp=0 -use_value_profile=1 -runs=20000000 2>&1 | FileCheck %s
diff --git a/test/fuzzer/value-profile-mem.test b/test/fuzzer/value-profile-mem.test
index 0b0c21d689ce..57c844e92261 100644
--- a/test/fuzzer/value-profile-mem.test
+++ b/test/fuzzer/value-profile-mem.test
@@ -1,3 +1,4 @@
+UNSUPPORTED: freebsd
CHECK: BINGO
RUN: %cpp_compiler %S/SingleMemcmpTest.cpp -o %t-SingleMemcmpTest
-RUN: not %t-SingleMemcmpTest -seed=1 -use_cmp=0 -use_value_profile=1 -runs=10000000 2>&1 | FileCheck %s
+RUN: not %run %t-SingleMemcmpTest -seed=1 -use_cmp=0 -use_value_profile=1 -runs=10000000 2>&1 | FileCheck %s
diff --git a/test/fuzzer/value-profile-set.test b/test/fuzzer/value-profile-set.test
index e2e3fb47f3ad..e55f1e4a853a 100644
--- a/test/fuzzer/value-profile-set.test
+++ b/test/fuzzer/value-profile-set.test
@@ -1,4 +1,4 @@
CHECK: BINGO
RUN: %cpp_compiler %S/FourIndependentBranchesTest.cpp -o %t-FourIndependentBranchesTest
-RUN: not %t-FourIndependentBranchesTest -seed=1 -use_cmp=0 -use_value_profile=1 -runs=100000000 2>&1 | FileCheck %s
+RUN: not %run %t-FourIndependentBranchesTest -seed=1 -use_cmp=0 -use_value_profile=1 -runs=100000000 2>&1 | FileCheck %s
diff --git a/test/fuzzer/value-profile-strcmp.test b/test/fuzzer/value-profile-strcmp.test
index f5c766a658f4..647121f22820 100644
--- a/test/fuzzer/value-profile-strcmp.test
+++ b/test/fuzzer/value-profile-strcmp.test
@@ -1,3 +1,4 @@
+UNSUPPORTED: freebsd
CHECK: BINGO
RUN: %cpp_compiler %S/SingleStrcmpTest.cpp -o %t-SingleStrcmpTest
-RUN: not %t-SingleStrcmpTest -seed=1 -use_cmp=0 -use_value_profile=1 -runs=10000000 2>&1 | FileCheck %s
+RUN: not %run %t-SingleStrcmpTest -seed=1 -use_cmp=0 -use_value_profile=1 -runs=10000000 2>&1 | FileCheck %s
diff --git a/test/fuzzer/value-profile-strncmp.test b/test/fuzzer/value-profile-strncmp.test
index 2dfe43c4abc5..b60b97f86f3e 100644
--- a/test/fuzzer/value-profile-strncmp.test
+++ b/test/fuzzer/value-profile-strncmp.test
@@ -1,3 +1,4 @@
+UNSUPPORTED: freebsd
CHECK: BINGO
RUN: %cpp_compiler %S/SingleStrncmpTest.cpp -o %t-SingleStrncmpTest
-RUN: not %t-SingleStrncmpTest -seed=1 -use_cmp=0 -use_value_profile=1 -runs=100000000 2>&1 | FileCheck %s
+RUN: not %run %t-SingleStrncmpTest -seed=1 -use_cmp=0 -use_value_profile=1 -runs=100000000 2>&1 | FileCheck %s
diff --git a/test/fuzzer/value-profile-switch.test b/test/fuzzer/value-profile-switch.test
index 7edb312a07b0..cc3d4944c0bf 100644
--- a/test/fuzzer/value-profile-switch.test
+++ b/test/fuzzer/value-profile-switch.test
@@ -1,5 +1,6 @@
+XFAIL: ios
CHECK: BINGO
RUN: %cpp_compiler %S/SwitchTest.cpp -o %t-SwitchTest
RUN: %cpp_compiler %S/Switch2Test.cpp -o %t-Switch2Test
-RUN: not %t-SwitchTest -use_cmp=0 -use_value_profile=1 -runs=100000000 -seed=1 2>&1 | FileCheck %s
-RUN: not %t-Switch2Test -use_cmp=0 -use_value_profile=1 -runs=100000000 -seed=1 2>&1 | FileCheck %s
+RUN: not %run %t-SwitchTest -use_cmp=0 -use_value_profile=1 -runs=100000000 -seed=1 2>&1 | FileCheck %s
+RUN: not %run %t-Switch2Test -use_cmp=0 -use_value_profile=1 -runs=100000000 -seed=1 2>&1 | FileCheck %s
diff --git a/test/hwasan/TestCases/Linux/aligned_alloc-alignment.cc b/test/hwasan/TestCases/Linux/aligned_alloc-alignment.cc
new file mode 100644
index 000000000000..a5dc7f661c7a
--- /dev/null
+++ b/test/hwasan/TestCases/Linux/aligned_alloc-alignment.cc
@@ -0,0 +1,25 @@
+// RUN: %clangxx_hwasan -O0 %s -o %t
+// RUN: %env_hwasan_opts=allocator_may_return_null=0 not %run %t 2>&1 | FileCheck %s
+// RUN: %env_hwasan_opts=allocator_may_return_null=1 %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-NULL
+
+// UNSUPPORTED: android
+
+// REQUIRES: stable-runtime
+
+#include <stdio.h>
+#include <stdlib.h>
+
+extern void *aligned_alloc(size_t alignment, size_t size);
+
+int main() {
+ void *p = aligned_alloc(17, 100);
+ // CHECK: ERROR: HWAddressSanitizer: invalid alignment requested in aligned_alloc: 17
+ // CHECK: {{#0 0x.* in .*}}{{aligned_alloc|memalign}}
+ // CHECK: {{#1 0x.* in main .*aligned_alloc-alignment.cc:}}[[@LINE-3]]
+ // CHECK: SUMMARY: HWAddressSanitizer: invalid-aligned-alloc-alignment
+
+ printf("pointer after failed aligned_alloc: %zd\n", (size_t)p);
+ // CHECK-NULL: pointer after failed aligned_alloc: 0
+
+ return 0;
+}
diff --git a/test/hwasan/TestCases/Linux/lit.local.cfg b/test/hwasan/TestCases/Linux/lit.local.cfg
new file mode 100644
index 000000000000..57271b8078a4
--- /dev/null
+++ b/test/hwasan/TestCases/Linux/lit.local.cfg
@@ -0,0 +1,9 @@
+def getRoot(config):
+ if not config.parent:
+ return config
+ return getRoot(config.parent)
+
+root = getRoot(config)
+
+if root.host_os not in ['Linux']:
+ config.unsupported = True
diff --git a/test/hwasan/TestCases/Linux/pvalloc-overflow.cc b/test/hwasan/TestCases/Linux/pvalloc-overflow.cc
new file mode 100644
index 000000000000..a4897c1279e7
--- /dev/null
+++ b/test/hwasan/TestCases/Linux/pvalloc-overflow.cc
@@ -0,0 +1,46 @@
+// RUN: %clangxx_hwasan -O0 %s -o %t
+// RUN: %env_hwasan_opts=allocator_may_return_null=0 not %run %t m1 2>&1 | FileCheck %s
+// RUN: %env_hwasan_opts=allocator_may_return_null=1 %run %t m1 2>&1 | FileCheck %s --check-prefix=CHECK-NULL
+// RUN: %env_hwasan_opts=allocator_may_return_null=0 not %run %t psm1 2>&1 | FileCheck %s
+// RUN: %env_hwasan_opts=allocator_may_return_null=1 %run %t psm1 2>&1 | FileCheck %s --check-prefix=CHECK-NULL
+
+// UNSUPPORTED: android
+
+// REQUIRES: stable-runtime
+
+// Checks that pvalloc overflows are caught. If the allocator is allowed to
+// return null, the errno should be set to ENOMEM.
+
+#include <assert.h>
+#include <errno.h>
+#include <malloc.h>
+#include <stdint.h>
+#include <string.h>
+#include <unistd.h>
+
+int main(int argc, char *argv[]) {
+ assert(argc == 2);
+ const char *action = argv[1];
+
+ const size_t page_size = sysconf(_SC_PAGESIZE);
+
+ void *p = nullptr;
+ if (!strcmp(action, "m1")) {
+ p = pvalloc((uintptr_t)-1);
+ } else if (!strcmp(action, "psm1")) {
+ p = pvalloc((uintptr_t)-(page_size - 1));
+ } else {
+ assert(0);
+ }
+
+ fprintf(stderr, "errno: %d\n", errno);
+
+ return p != nullptr;
+}
+
+// CHECK: {{ERROR: HWAddressSanitizer: pvalloc parameters overflow: size .* rounded up to system page size .* cannot be represented in type size_t}}
+// CHECK: {{#0 0x.* in .*pvalloc}}
+// CHECK: {{#1 0x.* in main .*pvalloc-overflow.cc:}}
+// CHECK: SUMMARY: HWAddressSanitizer: pvalloc-overflow
+
+// CHECK-NULL: errno: 12
diff --git a/test/hwasan/TestCases/Posix/lit.local.cfg b/test/hwasan/TestCases/Posix/lit.local.cfg
new file mode 100644
index 000000000000..60a9460820a6
--- /dev/null
+++ b/test/hwasan/TestCases/Posix/lit.local.cfg
@@ -0,0 +1,9 @@
+def getRoot(config):
+ if not config.parent:
+ return config
+ return getRoot(config.parent)
+
+root = getRoot(config)
+
+if root.host_os in ['Windows']:
+ config.unsupported = True
diff --git a/test/hwasan/TestCases/Posix/posix_memalign-alignment.cc b/test/hwasan/TestCases/Posix/posix_memalign-alignment.cc
new file mode 100644
index 000000000000..1ecc39c42f23
--- /dev/null
+++ b/test/hwasan/TestCases/Posix/posix_memalign-alignment.cc
@@ -0,0 +1,22 @@
+// RUN: %clangxx_hwasan -O0 %s -o %t
+// RUN: %env_hwasan_opts=allocator_may_return_null=0 not %run %t 2>&1 | FileCheck %s
+// RUN: %env_hwasan_opts=allocator_may_return_null=1 %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-NULL
+
+// REQUIRES: stable-runtime
+
+#include <stdio.h>
+#include <stdlib.h>
+
+int main() {
+ void *p = reinterpret_cast<void*>(42);
+ int res = posix_memalign(&p, 17, 100);
+ // CHECK: ERROR: HWAddressSanitizer: invalid alignment requested in posix_memalign: 17
+ // CHECK: {{#0 0x.* in .*posix_memalign}}
+ // CHECK: {{#1 0x.* in main .*posix_memalign-alignment.cc:}}[[@LINE-3]]
+ // CHECK: SUMMARY: HWAddressSanitizer: invalid-posix-memalign-alignment
+
+ printf("pointer after failed posix_memalign: %zd\n", (size_t)p);
+ // CHECK-NULL: pointer after failed posix_memalign: 42
+
+ return 0;
+}
diff --git a/test/msan/allocator_returns_null.cc b/test/hwasan/TestCases/allocator_returns_null.cc
index 583b5b4f76be..8d2ef38d4ab7 100644
--- a/test/msan/allocator_returns_null.cc
+++ b/test/hwasan/TestCases/allocator_returns_null.cc
@@ -1,42 +1,44 @@
-// Test the behavior of malloc/calloc/realloc/new when the allocation size is
-// more than MSan allocator's max allowed one.
-// By default (allocator_may_return_null=0) the process should crash.
-// With allocator_may_return_null=1 the allocator should return 0, except the
-// operator new(), which should crash anyway (operator new(std::nothrow) should
-// return nullptr, indeed).
+// Test the behavior of malloc/calloc/realloc/new when the allocation size
+// exceeds the HWASan allocator's max allowed one.
+// By default (allocator_may_return_null=0) the process should crash. With
+// allocator_may_return_null=1 the allocator should return 0 and set errno to
+// the appropriate error code.
//
-// RUN: %clangxx_msan -O0 %s -o %t
+// RUN: %clangxx_hwasan -O0 %s -o %t
// RUN: not %run %t malloc 2>&1 | FileCheck %s --check-prefix=CHECK-mCRASH
-// RUN: MSAN_OPTIONS=allocator_may_return_null=0 not %run %t malloc 2>&1 \
+// RUN: %env_hwasan_opts=allocator_may_return_null=0 not %run %t malloc 2>&1 \
// RUN: | FileCheck %s --check-prefix=CHECK-mCRASH
-// RUN: MSAN_OPTIONS=allocator_may_return_null=1 %run %t malloc 2>&1 \
+// RUN: %env_hwasan_opts=allocator_may_return_null=1 %run %t malloc 2>&1 \
// RUN: | FileCheck %s --check-prefix=CHECK-mNULL
-// RUN: MSAN_OPTIONS=allocator_may_return_null=0 not %run %t calloc 2>&1 \
+// RUN: %env_hwasan_opts=allocator_may_return_null=0 not %run %t calloc 2>&1 \
// RUN: | FileCheck %s --check-prefix=CHECK-cCRASH
-// RUN: MSAN_OPTIONS=allocator_may_return_null=1 %run %t calloc 2>&1 \
+// RUN: %env_hwasan_opts=allocator_may_return_null=1 %run %t calloc 2>&1 \
// RUN: | FileCheck %s --check-prefix=CHECK-cNULL
-// RUN: MSAN_OPTIONS=allocator_may_return_null=0 not %run %t calloc-overflow 2>&1 \
+// RUN: %env_hwasan_opts=allocator_may_return_null=0 not %run %t calloc-overflow 2>&1 \
// RUN: | FileCheck %s --check-prefix=CHECK-coCRASH
-// RUN: MSAN_OPTIONS=allocator_may_return_null=1 %run %t calloc-overflow 2>&1 \
+// RUN: %env_hwasan_opts=allocator_may_return_null=1 %run %t calloc-overflow 2>&1 \
// RUN: | FileCheck %s --check-prefix=CHECK-coNULL
-// RUN: MSAN_OPTIONS=allocator_may_return_null=0 not %run %t realloc 2>&1 \
+// RUN: %env_hwasan_opts=allocator_may_return_null=0 not %run %t realloc 2>&1 \
// RUN: | FileCheck %s --check-prefix=CHECK-rCRASH
-// RUN: MSAN_OPTIONS=allocator_may_return_null=1 %run %t realloc 2>&1 \
+// RUN: %env_hwasan_opts=allocator_may_return_null=1 %run %t realloc 2>&1 \
// RUN: | FileCheck %s --check-prefix=CHECK-rNULL
-// RUN: MSAN_OPTIONS=allocator_may_return_null=0 not %run %t realloc-after-malloc 2>&1 \
+// RUN: %env_hwasan_opts=allocator_may_return_null=0 not %run %t realloc-after-malloc 2>&1 \
// RUN: | FileCheck %s --check-prefix=CHECK-mrCRASH
-// RUN: MSAN_OPTIONS=allocator_may_return_null=1 %run %t realloc-after-malloc 2>&1 \
+// RUN: %env_hwasan_opts=allocator_may_return_null=1 %run %t realloc-after-malloc 2>&1 \
// RUN: | FileCheck %s --check-prefix=CHECK-mrNULL
-// RUN: MSAN_OPTIONS=allocator_may_return_null=0 not %run %t new 2>&1 \
+// RUN: %env_hwasan_opts=allocator_may_return_null=0 not %run %t new 2>&1 \
// RUN: | FileCheck %s --check-prefix=CHECK-nCRASH
-// RUN: MSAN_OPTIONS=allocator_may_return_null=1 not %run %t new 2>&1 \
-// RUN: | FileCheck %s --check-prefix=CHECK-nCRASH
-// RUN: MSAN_OPTIONS=allocator_may_return_null=0 not %run %t new-nothrow 2>&1 \
+// RUN: %env_hwasan_opts=allocator_may_return_null=1 not %run %t new 2>&1 \
+// RUN: | FileCheck %s --check-prefix=CHECK-nCRASH-OOM
+// RUN: %env_hwasan_opts=allocator_may_return_null=0 not %run %t new-nothrow 2>&1 \
// RUN: | FileCheck %s --check-prefix=CHECK-nnCRASH
-// RUN: MSAN_OPTIONS=allocator_may_return_null=1 %run %t new-nothrow 2>&1 \
+// RUN: %env_hwasan_opts=allocator_may_return_null=1 %run %t new-nothrow 2>&1 \
// RUN: | FileCheck %s --check-prefix=CHECK-nnNULL
-// UNSUPPORTED: win32
+// REQUIRES: stable-runtime
+
+// TODO(alekseyshl): Fix it.
+// UNSUPPORTED: android
#include <assert.h>
#include <errno.h>
@@ -47,21 +49,13 @@
#include <new>
int main(int argc, char **argv) {
- // Disable stderr buffering. Needed on Windows.
- setvbuf(stderr, NULL, _IONBF, 0);
-
assert(argc == 2);
const char *action = argv[1];
fprintf(stderr, "%s:\n", action);
- static const size_t kMaxAllowedMallocSizePlusOne =
-#if __LP64__ || defined(_WIN64)
- (8UL << 30) + 1;
-#else
- (2UL << 30) + 1;
-#endif
+ static const size_t kMaxAllowedMallocSizePlusOne = (2UL << 30) + 1;
- void *x = 0;
+ void *x = nullptr;
if (!strcmp(action, "malloc")) {
x = malloc(kMaxAllowedMallocSizePlusOne);
} else if (!strcmp(action, "calloc")) {
@@ -89,43 +83,36 @@ int main(int argc, char **argv) {
fprintf(stderr, "errno: %d\n", errno);
- // The NULL pointer is printed differently on different systems, while (long)0
- // is always the same.
- fprintf(stderr, "x: %lx\n", (long)x);
free(x);
- return x != 0;
+ return x != nullptr;
}
// CHECK-mCRASH: malloc:
-// CHECK-mCRASH: MemorySanitizer's allocator is terminating the process
+// CHECK-mCRASH: SUMMARY: HWAddressSanitizer: allocation-size-too-big
// CHECK-cCRASH: calloc:
-// CHECK-cCRASH: MemorySanitizer's allocator is terminating the process
+// CHECK-cCRASH: SUMMARY: HWAddressSanitizer: allocation-size-too-big
// CHECK-coCRASH: calloc-overflow:
-// CHECK-coCRASH: MemorySanitizer's allocator is terminating the process
+// CHECK-coCRASH: SUMMARY: HWAddressSanitizer: calloc-overflow
// CHECK-rCRASH: realloc:
-// CHECK-rCRASH: MemorySanitizer's allocator is terminating the process
+// CHECK-rCRASH: SUMMARY: HWAddressSanitizer: allocation-size-too-big
// CHECK-mrCRASH: realloc-after-malloc:
-// CHECK-mrCRASH: MemorySanitizer's allocator is terminating the process
+// CHECK-mrCRASH: SUMMARY: HWAddressSanitizer: allocation-size-too-big
// CHECK-nCRASH: new:
-// CHECK-nCRASH: MemorySanitizer's allocator is terminating the process
+// CHECK-nCRASH: SUMMARY: HWAddressSanitizer: allocation-size-too-big
+// CHECK-nCRASH-OOM: new:
+// CHECK-nCRASH-OOM: SUMMARY: HWAddressSanitizer: out-of-memory
// CHECK-nnCRASH: new-nothrow:
-// CHECK-nnCRASH: MemorySanitizer's allocator is terminating the process
+// CHECK-nnCRASH: SUMMARY: HWAddressSanitizer: allocation-size-too-big
// CHECK-mNULL: malloc:
// CHECK-mNULL: errno: 12
-// CHECK-mNULL: x: 0
// CHECK-cNULL: calloc:
// CHECK-cNULL: errno: 12
-// CHECK-cNULL: x: 0
// CHECK-coNULL: calloc-overflow:
// CHECK-coNULL: errno: 12
-// CHECK-coNULL: x: 0
// CHECK-rNULL: realloc:
// CHECK-rNULL: errno: 12
-// CHECK-rNULL: x: 0
// CHECK-mrNULL: realloc-after-malloc:
// CHECK-mrNULL: errno: 12
-// CHECK-mrNULL: x: 0
// CHECK-nnNULL: new-nothrow:
-// CHECK-nnNULL: x: 0
diff --git a/test/hwasan/TestCases/check-interface.cc b/test/hwasan/TestCases/check-interface.cc
new file mode 100644
index 000000000000..7ad911480359
--- /dev/null
+++ b/test/hwasan/TestCases/check-interface.cc
@@ -0,0 +1,22 @@
+// RUN: %clangxx_hwasan -mllvm -hwasan-instrument-with-calls=1 -O0 %s -o %t
+// RUN: %clangxx_hwasan -mllvm -hwasan-instrument-with-calls=1 -O0 %s -o %t -fsanitize-recover=hwaddress
+
+// REQUIRES: stable-runtime
+
+// Utilizes all flavors of __hwasan_load/store interface functions to verify
+// that the instrumentation and the interface provided by HWASan do match.
+// In case of a discrepancy, this test fails to link.
+
+#include <sanitizer/hwasan_interface.h>
+
+#define F(T) void f_##T(T *a, T *b) { *a = *b; }
+
+F(uint8_t)
+F(uint16_t)
+F(uint32_t)
+F(uint64_t)
+
+typedef unsigned V32 __attribute__((__vector_size__(32)));
+F(V32)
+
+int main() {}
diff --git a/test/hwasan/TestCases/stack-oob.cc b/test/hwasan/TestCases/stack-oob.cc
new file mode 100644
index 000000000000..60b9a6295005
--- /dev/null
+++ b/test/hwasan/TestCases/stack-oob.cc
@@ -0,0 +1,25 @@
+// RUN: %clangxx_hwasan -DSIZE=16 -O0 %s -o %t && not %run %t 2>&1 | FileCheck %s
+// RUN: %clangxx_hwasan -DSIZE=64 -O0 %s -o %t && not %run %t 2>&1 | FileCheck %s
+// RUN: %clangxx_hwasan -DSIZE=0x1000 -O0 %s -o %t && not %run %t 2>&1 | FileCheck %s
+
+// REQUIRES: stable-runtime
+
+#include <stdlib.h>
+#include <sanitizer/hwasan_interface.h>
+
+__attribute__((noinline))
+int f() {
+ char z[SIZE];
+ char *volatile p = z;
+ return p[SIZE];
+}
+
+int main() {
+ return f();
+ // CHECK: READ of size 1 at
+ // CHECK: #0 {{.*}} in f{{.*}}stack-oob.cc:14
+
+ // CHECK: HWAddressSanitizer can not describe address in more detail.
+
+ // CHECK: SUMMARY: HWAddressSanitizer: tag-mismatch {{.*}} in f
+}
diff --git a/test/hwasan/TestCases/stack-uar.cc b/test/hwasan/TestCases/stack-uar.cc
new file mode 100644
index 000000000000..e99dcceed533
--- /dev/null
+++ b/test/hwasan/TestCases/stack-uar.cc
@@ -0,0 +1,23 @@
+// RUN: %clangxx_hwasan -O0 %s -o %t && not %run %t 2>&1 | FileCheck %s
+
+// REQUIRES: stable-runtime
+
+#include <stdlib.h>
+#include <sanitizer/hwasan_interface.h>
+
+__attribute__((noinline))
+char *f() {
+ char z[0x1000];
+ char *volatile p = z;
+ return p;
+}
+
+int main() {
+ return *f();
+ // CHECK: READ of size 1 at
+ // CHECK: #0 {{.*}} in main{{.*}}stack-uar.cc:16
+
+ // CHECK: HWAddressSanitizer can not describe address in more detail.
+
+ // CHECK: SUMMARY: HWAddressSanitizer: tag-mismatch {{.*}} in main
+}
diff --git a/test/hwasan/TestCases/use-after-free.c b/test/hwasan/TestCases/use-after-free.c
new file mode 100644
index 000000000000..b9f6060112c1
--- /dev/null
+++ b/test/hwasan/TestCases/use-after-free.c
@@ -0,0 +1,39 @@
+// RUN: %clang_hwasan -O0 -DLOAD %s -o %t && not %run %t 2>&1 | FileCheck %s --check-prefixes=CHECK,LOAD
+// RUN: %clang_hwasan -O1 -DLOAD %s -o %t && not %run %t 2>&1 | FileCheck %s --check-prefixes=CHECK,LOAD
+// RUN: %clang_hwasan -O2 -DLOAD %s -o %t && not %run %t 2>&1 | FileCheck %s --check-prefixes=CHECK,LOAD
+// RUN: %clang_hwasan -O3 -DLOAD %s -o %t && not %run %t 2>&1 | FileCheck %s --check-prefixes=CHECK,LOAD
+
+// RUN: %clang_hwasan -O0 -DSTORE %s -o %t && not %run %t 2>&1 | FileCheck %s --check-prefixes=CHECK,STORE
+
+// REQUIRES: stable-runtime
+
+#include <stdlib.h>
+#include <sanitizer/hwasan_interface.h>
+
+int main() {
+ __hwasan_enable_allocator_tagging();
+ char * volatile x = (char*)malloc(10);
+ free(x);
+ __hwasan_disable_allocator_tagging();
+#ifdef STORE
+ x[5] = 42;
+#endif
+#ifdef LOAD
+ return x[5];
+#endif
+ // LOAD: READ of size 1 at
+ // LOAD: #0 {{.*}} in main {{.*}}use-after-free.c:22
+
+ // STORE: WRITE of size 1 at
+ // STORE: #0 {{.*}} in main {{.*}}use-after-free.c:19
+
+ // CHECK: freed here:
+ // CHECK: #0 {{.*}} in {{.*}}free{{.*}} {{.*}}hwasan_interceptors.cc
+ // CHECK: #1 {{.*}} in main {{.*}}use-after-free.c:16
+
+ // CHECK: previously allocated here:
+ // CHECK: #0 {{.*}} in {{.*}}malloc{{.*}} {{.*}}hwasan_interceptors.cc
+ // CHECK: #1 {{.*}} in main {{.*}}use-after-free.c:15
+
+ // CHECK: SUMMARY: HWAddressSanitizer: tag-mismatch {{.*}} in main
+}
diff --git a/test/hwasan/TestCases/use-after-free.cc b/test/hwasan/TestCases/use-after-free.cc
deleted file mode 100644
index 37637898d7a1..000000000000
--- a/test/hwasan/TestCases/use-after-free.cc
+++ /dev/null
@@ -1,39 +0,0 @@
-// RUN: %clangxx_hwasan -O0 -DLOAD %s -o %t && not %run %t 2>&1 | FileCheck %s --check-prefixes=CHECK,LOAD
-// RUN: %clangxx_hwasan -O1 -DLOAD %s -o %t && not %run %t 2>&1 | FileCheck %s --check-prefixes=CHECK,LOAD
-// RUN: %clangxx_hwasan -O2 -DLOAD %s -o %t && not %run %t 2>&1 | FileCheck %s --check-prefixes=CHECK,LOAD
-// RUN: %clangxx_hwasan -O3 -DLOAD %s -o %t && not %run %t 2>&1 | FileCheck %s --check-prefixes=CHECK,LOAD
-
-// RUN: %clangxx_hwasan -O0 -DSTORE %s -o %t && not %run %t 2>&1 | FileCheck %s --check-prefixes=CHECK,STORE
-
-// REQUIRES: stable-runtime
-
-#include <stdlib.h>
-#include <sanitizer/hwasan_interface.h>
-
-int main() {
- __hwasan_enable_allocator_tagging();
- char * volatile x = (char*)malloc(10);
- free(x);
- __hwasan_disable_allocator_tagging();
-#ifdef STORE
- x[5] = 42;
-#endif
-#ifdef LOAD
- return x[5];
-#endif
- // LOAD: READ of size 1 at
- // LOAD: #0 {{.*}} in main {{.*}}use-after-free.cc:22
-
- // STORE: WRITE of size 1 at
- // STORE: #0 {{.*}} in main {{.*}}use-after-free.cc:19
-
- // CHECK: freed here:
- // CHECK: #0 {{.*}} in free {{.*}}hwasan_interceptors.cc
- // CHECK: #1 {{.*}} in main {{.*}}use-after-free.cc:16
-
- // CHECK: previously allocated here:
- // CHECK: #0 {{.*}} in __interceptor_malloc {{.*}}hwasan_interceptors.cc
- // CHECK: #1 {{.*}} in main {{.*}}use-after-free.cc:15
-
- // CHECK: SUMMARY: HWAddressSanitizer: tag-mismatch {{.*}} in main
-}
diff --git a/test/hwasan/lit.cfg b/test/hwasan/lit.cfg
index 4f099af5b7fc..3ebba51d05e4 100644
--- a/test/hwasan/lit.cfg
+++ b/test/hwasan/lit.cfg
@@ -9,7 +9,7 @@ config.name = 'HWAddressSanitizer' + getattr(config, 'name_suffix', 'default')
config.test_source_root = os.path.dirname(__file__)
# Setup default compiler flags used with -fsanitize=memory option.
-clang_hwasan_cflags = ["-fsanitize=hwaddress", config.target_cflags] + config.debug_info_flags
+clang_hwasan_cflags = ["-fsanitize=hwaddress", "-mllvm", "-hwasan-generate-tags-with-calls", config.target_cflags] + config.debug_info_flags
clang_hwasan_cxxflags = config.cxx_mode_flags + clang_hwasan_cflags
def build_invocation(compile_flags):
@@ -18,7 +18,7 @@ def build_invocation(compile_flags):
config.substitutions.append( ("%clang_hwasan ", build_invocation(clang_hwasan_cflags)) )
config.substitutions.append( ("%clangxx_hwasan ", build_invocation(clang_hwasan_cxxflags)) )
-default_hwasan_opts_str = ':'.join(['disable_allocator_tagging=1'] + config.default_sanitizer_opts)
+default_hwasan_opts_str = ':'.join(['disable_allocator_tagging=1', 'random_tags=0'] + config.default_sanitizer_opts)
if default_hwasan_opts_str:
config.environment['HWASAN_OPTIONS'] = default_hwasan_opts_str
default_hwasan_opts_str += ':'
diff --git a/test/lit.common.cfg b/test/lit.common.cfg
index 0840f65a7161..5274b49c654f 100644
--- a/test/lit.common.cfg
+++ b/test/lit.common.cfg
@@ -7,6 +7,7 @@ import os
import platform
import re
import subprocess
+import json
import lit.formats
import lit.util
@@ -37,7 +38,11 @@ if compiler_id == "Clang":
# reports and stack traces even with minimal debug info.
config.debug_info_flags = ["-gline-tables-only"]
if platform.system() == 'Windows':
+ # On Windows, use CodeView with column info instead of DWARF. Both VS and
+ # windbg do not behave well when column info is enabled, but users have
+ # requested it because it makes ASan reports more precise.
config.debug_info_flags.append("-gcodeview")
+ config.debug_info_flags.append("-gcolumn-info")
elif compiler_id == 'GNU':
config.cxx_mode_flags = ["-x c++"]
config.debug_info_flags = ["-g"]
@@ -86,8 +91,10 @@ config.environment['PATH'] = path
if platform.system() == 'Windows' and '-win' in config.target_triple:
config.environment['LIB'] = os.environ['LIB']
+config.available_features.add(config.host_os.lower())
+
if re.match(r'^x86_64.*-linux', config.target_triple):
- config.available_features.add("x86_64-linux")
+ config.available_features.add("x86_64-linux")
# Use ugly construction to explicitly prohibit "clang", "clang++" etc.
# in RUN lines.
@@ -100,17 +107,50 @@ if config.emulator:
config.substitutions.append( ('%run', config.emulator) )
config.substitutions.append( ('%env ', "env ") )
config.compile_wrapper = ""
-elif config.ios:
+elif config.host_os == 'Darwin' and config.apple_platform != "osx":
+ # Darwin tests can be targetting macOS, a device or a simulator. All devices
+ # are declared as "ios", even for iOS derivatives (tvOS, watchOS). Similarly,
+ # all simulators are "iossim". See the table below.
+ #
+ # =========================================================================
+ # Target | Feature set
+ # =========================================================================
+ # macOS | darwin
+ # iOS device | darwin, ios
+ # iOS simulator | darwin, ios, iossim
+ # tvOS device | darwin, ios, tvos
+ # tvOS simulator | darwin, ios, iossim, tvos, tvossim
+ # watchOS device | darwin, ios, watchos
+ # watchOS simulator | darwin, ios, iossim, watchos, watchossim
+ # =========================================================================
+
+ ios_or_iossim = "iossim" if config.apple_platform.endswith("sim") else "ios"
+
config.available_features.add('ios')
- device_id_env = "SANITIZER_IOSSIM_TEST_DEVICE_IDENTIFIER" if config.iossim else "SANITIZER_IOS_TEST_DEVICE_IDENTIFIER"
- if device_id_env in os.environ: config.environment[device_id_env] = os.environ[device_id_env]
+ if ios_or_iossim == "iossim":
+ config.available_features.add('iossim')
+ if config.apple_platform != "ios" and config.apple_platform != "iossim":
+ config.available_features.add(config.apple_platform)
+
ios_commands_dir = os.path.join(config.compiler_rt_src_root, "test", "sanitizer_common", "ios_commands")
- run_wrapper = os.path.join(ios_commands_dir, "iossim_run.py" if config.iossim else "ios_run.py")
+
+ device_id_env = "SANITIZER_" + ios_or_iossim.upper() + "_TEST_DEVICE_IDENTIFIER"
+ run_wrapper = os.path.join(ios_commands_dir, ios_or_iossim + "_run.py")
+ env_wrapper = os.path.join(ios_commands_dir, ios_or_iossim + "_env.py")
+ compile_wrapper = os.path.join(ios_commands_dir, ios_or_iossim + "_compile.py")
+ prepare_script = os.path.join(ios_commands_dir, ios_or_iossim + "_prepare.py")
+
+ if device_id_env in os.environ:
+ config.environment[device_id_env] = os.environ[device_id_env]
config.substitutions.append(('%run', run_wrapper))
- env_wrapper = os.path.join(ios_commands_dir, "iossim_env.py" if config.iossim else "ios_env.py")
config.substitutions.append(('%env ', env_wrapper + " "))
- compile_wrapper = os.path.join(ios_commands_dir, "iossim_compile.py" if config.iossim else "ios_compile.py")
config.compile_wrapper = compile_wrapper
+
+ prepare_output = subprocess.check_output([prepare_script, config.apple_platform, config.clang]).strip()
+ if len(prepare_output) > 0: print(prepare_output)
+ prepare_output_json = prepare_output.split("\n")[-1]
+ prepare_output = json.loads(prepare_output_json)
+ config.environment.update(prepare_output["env"])
elif config.android:
config.available_features.add('android')
compile_wrapper = os.path.join(config.compiler_rt_src_root, "test", "sanitizer_common", "android_commands", "android_compile.py") + " "
@@ -197,8 +237,19 @@ if config.host_os == 'Darwin':
pass
config.substitutions.append( ("%macos_min_target_10_11", "-mmacosx-version-min=10.11") )
+
+ isIOS = config.apple_platform != "osx"
+ # rdar://problem/22207160
+ config.substitutions.append( ("%darwin_min_target_with_full_runtime_arc_support",
+ "-miphoneos-version-min=9.0" if isIOS else "-mmacosx-version-min=10.11") )
+
+ # 32-bit iOS simulator is deprecated and removed in latest Xcode.
+ if config.apple_platform == "iossim":
+ if config.target_arch == "i386":
+ config.unsupported = True
else:
config.substitutions.append( ("%macos_min_target_10_11", "") )
+ config.substitutions.append( ("%darwin_min_target_with_full_runtime_arc_support", "") )
if config.android:
adb = os.environ.get('ADB', 'adb')
@@ -265,6 +316,8 @@ if config.lto_supported:
config.lto_flags += ["-flto=thin"]
else:
config.lto_flags += ["-flto"]
+ if config.use_newpm:
+ config.lto_flags += ["-fexperimental-new-pass-manager"]
# Ask llvm-config about assertion mode.
try:
@@ -291,20 +344,43 @@ if platform.system() == 'Windows':
if platform.system() == 'Darwin':
lit_config.parallelism_groups["darwin-64bit-sanitizer"] = 3
-if config.host_os == 'Darwin':
- config.substitutions.append( ("%ld_flags_rpath_exe", '-Wl,-rpath,@executable_path/ %dynamiclib') )
- config.substitutions.append( ("%ld_flags_rpath_so", '-install_name @rpath/`basename %dynamiclib`') )
-elif config.host_os == 'FreeBSD':
- config.substitutions.append( ("%ld_flags_rpath_exe", "-Wl,-z,origin -Wl,-rpath,\$ORIGIN -L%T -l%xdynamiclib_namespec") )
- config.substitutions.append( ("%ld_flags_rpath_so", '') )
-elif config.host_os == 'Linux':
- config.substitutions.append( ("%ld_flags_rpath_exe", "-Wl,-rpath,\$ORIGIN -L%T -l%xdynamiclib_namespec") )
- config.substitutions.append( ("%ld_flags_rpath_so", '') )
-
-# Must be defined after the substitutions that use %dynamiclib.
-config.substitutions.append( ("%dynamiclib", '%T/%xdynamiclib_filename') )
-config.substitutions.append( ("%xdynamiclib_filename", 'lib%xdynamiclib_namespec.so') )
-config.substitutions.append( ("%xdynamiclib_namespec", '%basename_t.dynamic') )
+# The current implementation of the tools in sanitizer_common/ios_comamnds
+# do not support parallel execution so force sequential execution of the
+# tests on iOS devices.
+if config.host_os == 'Darwin' and config.apple_platform != "osx" and not config.apple_platform.endswith("sim"):
+ lit_config.warning("iOS device test cases being run sequentially")
+ lit_config.parallelism_groups["darwin-ios-device-sanitizer"] = 1
+
+# Multiple substitutions are necessary to support multiple shared objects used
+# at once.
+# Note that substitutions with numbers have to be defined first to avoid
+# being subsumed by substitutions with smaller postfix.
+for postfix in ["2", "1", ""]:
+ if config.host_os == 'Darwin':
+ config.substitutions.append( ("%ld_flags_rpath_exe" + postfix, '-Wl,-rpath,@executable_path/ %dynamiclib' + postfix) )
+ config.substitutions.append( ("%ld_flags_rpath_so" + postfix, '-install_name @rpath/`basename %dynamiclib{}`'.format(postfix)) )
+ elif config.host_os in ('FreeBSD', 'NetBSD', 'OpenBSD'):
+ config.substitutions.append( ("%ld_flags_rpath_exe" + postfix, "-Wl,-z,origin -Wl,-rpath,\$ORIGIN -L%T -l%xdynamiclib_namespec" + postfix) )
+ config.substitutions.append( ("%ld_flags_rpath_so" + postfix, '') )
+ elif config.host_os == 'Linux':
+ config.substitutions.append( ("%ld_flags_rpath_exe" + postfix, "-Wl,-rpath,\$ORIGIN -L%T -l%xdynamiclib_namespec" + postfix) )
+ config.substitutions.append( ("%ld_flags_rpath_so" + postfix, '') )
+ elif config.host_os == 'SunOS':
+ config.substitutions.append( ("%ld_flags_rpath_exe" + postfix, "-Wl,-R\$ORIGIN -L%T -l%xdynamiclib_namespec" + postfix) )
+ config.substitutions.append( ("%ld_flags_rpath_so" + postfix, '') )
+
+ # Must be defined after the substitutions that use %dynamiclib.
+ config.substitutions.append( ("%dynamiclib" + postfix, '%T/%xdynamiclib_filename' + postfix) )
+ config.substitutions.append( ("%xdynamiclib_filename" + postfix, 'lib%xdynamiclib_namespec{}.so'.format(postfix)) )
+ config.substitutions.append( ("%xdynamiclib_namespec", '%basename_t.dynamic') )
+
+# Provide a substituion that can be used to tell Clang to use a static libstdc++.
+# The substitution expands to nothing on non Linux platforms.
+# FIXME: This should check the target OS, not the host OS.
+if config.host_os == 'Linux':
+ config.substitutions.append( ("%linux_static_libstdcplusplus", "-stdlib=libstdc++ -static-libstdc++") )
+else:
+ config.substitutions.append( ("%linux_static_libstdcplusplus", "") )
config.default_sanitizer_opts = []
if config.host_os == 'Darwin':
diff --git a/test/lit.common.configured.in b/test/lit.common.configured.in
index 32a88200bf2d..63d55bfdea81 100644
--- a/test/lit.common.configured.in
+++ b/test/lit.common.configured.in
@@ -16,6 +16,7 @@ set_default("llvm_src_root", "@LLVM_MAIN_SRC_DIR@")
set_default("llvm_obj_root", "@LLVM_BINARY_DIR@")
set_default("compiler_rt_src_root", "@COMPILER_RT_SOURCE_DIR@")
set_default("compiler_rt_obj_root", "@COMPILER_RT_BINARY_DIR@")
+set_default("enable_per_target_runtime_dir", @LLVM_ENABLE_PER_TARGET_RUNTIME_DIR_PYBOOL@)
set_default("llvm_tools_dir", "@LLVM_TOOLS_DIR@")
set_default("llvm_shlib_dir", "@LLVM_LIBRARY_OUTPUT_INTDIR@")
set_default("gold_executable", "@GOLD_EXECUTABLE@")
@@ -26,17 +27,22 @@ set_default("compiler_rt_debug", @COMPILER_RT_DEBUG_PYBOOL@)
set_default("compiler_rt_libdir", "@COMPILER_RT_RESOLVED_LIBRARY_OUTPUT_DIR@")
set_default("emulator", "@COMPILER_RT_EMULATOR@")
set_default("asan_shadow_scale", "@COMPILER_RT_ASAN_SHADOW_SCALE@")
-set_default("ios", False)
-set_default("iossim", False)
+set_default("apple_platform", "osx")
set_default("sanitizer_can_use_cxxabi", @SANITIZER_CAN_USE_CXXABI_PYBOOL@)
set_default("has_lld", @COMPILER_RT_HAS_LLD_PYBOOL@)
set_default("can_symbolize", @CAN_SYMBOLIZE@)
set_default("use_lld", False)
set_default("use_thinlto", False)
set_default("use_lto", config.use_thinlto)
+set_default("use_newpm", False)
set_default("android", @ANDROID_PYBOOL@)
config.available_features.add('target-is-%s' % config.target_arch)
+if config.enable_per_target_runtime_dir:
+ set_default("target_suffix", "")
+else:
+ set_default("target_suffix", "-%s" % config.target_arch)
+
# LLVM tools dir can be passed in lit parameters, so try to
# apply substitution.
try:
diff --git a/test/lsan/TestCases/Linux/fork_with_threads.cc b/test/lsan/TestCases/Linux/fork_with_threads.cc
new file mode 100644
index 000000000000..221c5d249d77
--- /dev/null
+++ b/test/lsan/TestCases/Linux/fork_with_threads.cc
@@ -0,0 +1,35 @@
+// Test forked process does not run lsan.
+// RUN: %clangxx_lsan %s -o %t && %run %t 2>&1 | FileCheck %s
+
+#include <pthread.h>
+#include <stdlib.h>
+#include <sys/wait.h>
+#include <unistd.h>
+
+static pthread_barrier_t barrier;
+
+// CHECK-NOT: SUMMARY: {{(Leak|Address)}}Sanitizer:
+static void *thread_func(void *arg) {
+ void *buffer = malloc(1337);
+ pthread_barrier_wait(&barrier);
+ for (;;)
+ pthread_yield();
+ return 0;
+}
+
+int main() {
+ pthread_barrier_init(&barrier, 0, 2);
+ pthread_t tid;
+ int res = pthread_create(&tid, 0, thread_func, 0);
+ pthread_barrier_wait(&barrier);
+ pthread_barrier_destroy(&barrier);
+
+ pid_t pid = fork();
+ if (pid > 0) {
+ int status = 0;
+ waitpid(pid, &status, 0);
+ }
+ return 0;
+}
+
+// CHECK: WARNING: LeakSanitizer is disabled in forked process
diff --git a/test/lsan/TestCases/Linux/log-path_test.cc b/test/lsan/TestCases/Linux/log-path_test.cc
new file mode 100644
index 000000000000..a31b4f64acc5
--- /dev/null
+++ b/test/lsan/TestCases/Linux/log-path_test.cc
@@ -0,0 +1,26 @@
+// RUN: %clangxx_lsan %s -o %t
+// The globs below do not work in the lit shell.
+
+// Regular run.
+// RUN: %env_lsan_opts="use_stacks=0" not %run %t > %t.out 2>&1
+// RUN: FileCheck %s --check-prefix=CHECK-ERROR < %t.out
+
+// Good log_path.
+// RUN: rm -f %t.log.*
+// RUN: %env_lsan_opts="use_stacks=0:log_path='"%t.log"'" not %run %t > %t.out 2>&1
+// RUN: FileCheck %s --check-prefix=CHECK-ERROR < %t.log.*
+
+#include <stdio.h>
+#include <stdlib.h>
+#include "sanitizer_common/print_address.h"
+
+int main() {
+ void *stack_var = malloc(1337);
+ print_address("Test alloc: ", 1, stack_var);
+ // Do not return from main to prevent the pointer from going out of scope.
+ exit(0);
+}
+
+// CHECK-ERROR: LeakSanitizer: detected memory leaks
+// CHECK-ERROR: Direct leak of 1337 byte(s) in 1 object(s) allocated from
+// CHECK-ERROR: SUMMARY: {{(Leak|Address)}}Sanitizer:
diff --git a/test/lsan/TestCases/Linux/use_tls_dynamic.cc b/test/lsan/TestCases/Linux/use_tls_dynamic.cc
index f5df231ba9a6..4d70a46f8183 100644
--- a/test/lsan/TestCases/Linux/use_tls_dynamic.cc
+++ b/test/lsan/TestCases/Linux/use_tls_dynamic.cc
@@ -5,7 +5,7 @@
// RUN: %env_lsan_opts=$LSAN_BASE:"use_tls=0" not %run %t 2>&1 | FileCheck %s
// RUN: %env_lsan_opts=$LSAN_BASE:"use_tls=1" %run %t 2>&1
// RUN: %env_lsan_opts="" %run %t 2>&1
-// UNSUPPORTED: i386-linux,arm
+// UNSUPPORTED: i386-linux,arm,powerpc
#ifndef BUILD_DSO
#include <assert.h>
diff --git a/test/lsan/TestCases/Posix/lit.local.cfg b/test/lsan/TestCases/Posix/lit.local.cfg
new file mode 100644
index 000000000000..60a9460820a6
--- /dev/null
+++ b/test/lsan/TestCases/Posix/lit.local.cfg
@@ -0,0 +1,9 @@
+def getRoot(config):
+ if not config.parent:
+ return config
+ return getRoot(config.parent)
+
+root = getRoot(config)
+
+if root.host_os in ['Windows']:
+ config.unsupported = True
diff --git a/test/lsan/TestCases/allocator_returns_null.cc b/test/lsan/TestCases/allocator_returns_null.cc
deleted file mode 100644
index 28dd696dc673..000000000000
--- a/test/lsan/TestCases/allocator_returns_null.cc
+++ /dev/null
@@ -1,131 +0,0 @@
-// Test the behavior of malloc/calloc/realloc/new when the allocation size is
-// more than LSan allocator's max allowed one.
-// By default (allocator_may_return_null=0) the process should crash.
-// With allocator_may_return_null=1 the allocator should return 0, except the
-// operator new(), which should crash anyway (operator new(std::nothrow) should
-// return nullptr, indeed).
-//
-// RUN: %clangxx_lsan -O0 %s -o %t
-// RUN: not %run %t malloc 2>&1 | FileCheck %s --check-prefix=CHECK-mCRASH
-// RUN: %env_lsan_opts=allocator_may_return_null=0 not %run %t malloc 2>&1 \
-// RUN: | FileCheck %s --check-prefix=CHECK-mCRASH
-// RUN: %env_lsan_opts=allocator_may_return_null=1 %run %t malloc 2>&1 \
-// RUN: | FileCheck %s --check-prefix=CHECK-mNULL
-// RUN: %env_lsan_opts=allocator_may_return_null=0 not %run %t calloc 2>&1 \
-// RUN: | FileCheck %s --check-prefix=CHECK-cCRASH
-// RUN: %env_lsan_opts=allocator_may_return_null=1 %run %t calloc 2>&1 \
-// RUN: | FileCheck %s --check-prefix=CHECK-cNULL
-// RUN: %env_lsan_opts=allocator_may_return_null=0 not %run %t calloc-overflow 2>&1 \
-// RUN: | FileCheck %s --check-prefix=CHECK-coCRASH
-// RUN: %env_lsan_opts=allocator_may_return_null=1 %run %t calloc-overflow 2>&1 \
-// RUN: | FileCheck %s --check-prefix=CHECK-coNULL
-// RUN: %env_lsan_opts=allocator_may_return_null=0 not %run %t realloc 2>&1 \
-// RUN: | FileCheck %s --check-prefix=CHECK-rCRASH
-// RUN: %env_lsan_opts=allocator_may_return_null=1 %run %t realloc 2>&1 \
-// RUN: | FileCheck %s --check-prefix=CHECK-rNULL
-// RUN: %env_lsan_opts=allocator_may_return_null=0 not %run %t realloc-after-malloc 2>&1 \
-// RUN: | FileCheck %s --check-prefix=CHECK-mrCRASH
-// RUN: %env_lsan_opts=allocator_may_return_null=1 %run %t realloc-after-malloc 2>&1 \
-// RUN: | FileCheck %s --check-prefix=CHECK-mrNULL
-// RUN: %env_lsan_opts=allocator_may_return_null=0 not %run %t new 2>&1 \
-// RUN: | FileCheck %s --check-prefix=CHECK-nCRASH
-// RUN: %env_lsan_opts=allocator_may_return_null=1 not %run %t new 2>&1 \
-// RUN: | FileCheck %s --check-prefix=CHECK-nCRASH
-// RUN: %env_lsan_opts=allocator_may_return_null=0 not %run %t new-nothrow 2>&1 \
-// RUN: | FileCheck %s --check-prefix=CHECK-nnCRASH
-// RUN: %env_lsan_opts=allocator_may_return_null=1 %run %t new-nothrow 2>&1 \
-// RUN: | FileCheck %s --check-prefix=CHECK-nnNULL
-
-#include <assert.h>
-#include <errno.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <limits>
-#include <new>
-
-int main(int argc, char **argv) {
- // Disable stderr buffering. Needed on Windows.
- setvbuf(stderr, NULL, _IONBF, 0);
-
- assert(argc == 2);
- const char *action = argv[1];
- fprintf(stderr, "%s:\n", action);
-
- // Use max of ASan and LSan allocator limits to cover both "lsan" and
- // "lsan + asan" configs.
- static const size_t kMaxAllowedMallocSizePlusOne =
-#if __LP64__ || defined(_WIN64)
- (1ULL << 40) + 1;
-#else
- (3UL << 30) + 1;
-#endif
-
- void *x = 0;
- if (!strcmp(action, "malloc")) {
- x = malloc(kMaxAllowedMallocSizePlusOne);
- } else if (!strcmp(action, "calloc")) {
- x = calloc((kMaxAllowedMallocSizePlusOne / 4) + 1, 4);
- } else if (!strcmp(action, "calloc-overflow")) {
- volatile size_t kMaxSizeT = std::numeric_limits<size_t>::max();
- size_t kArraySize = 4096;
- volatile size_t kArraySize2 = kMaxSizeT / kArraySize + 10;
- x = calloc(kArraySize, kArraySize2);
- } else if (!strcmp(action, "realloc")) {
- x = realloc(0, kMaxAllowedMallocSizePlusOne);
- } else if (!strcmp(action, "realloc-after-malloc")) {
- char *t = (char*)malloc(100);
- *t = 42;
- x = realloc(t, kMaxAllowedMallocSizePlusOne);
- assert(*t == 42);
- free(t);
- } else if (!strcmp(action, "new")) {
- x = operator new(kMaxAllowedMallocSizePlusOne);
- } else if (!strcmp(action, "new-nothrow")) {
- x = operator new(kMaxAllowedMallocSizePlusOne, std::nothrow);
- } else {
- assert(0);
- }
-
- fprintf(stderr, "errno: %d\n", errno);
-
- // The NULL pointer is printed differently on different systems, while (long)0
- // is always the same.
- fprintf(stderr, "x: %zu\n", (size_t)x);
- free(x);
-
- return x != 0;
-}
-
-// CHECK-mCRASH: malloc:
-// CHECK-mCRASH: Sanitizer's allocator is terminating the process
-// CHECK-cCRASH: calloc:
-// CHECK-cCRASH: Sanitizer's allocator is terminating the process
-// CHECK-coCRASH: calloc-overflow:
-// CHECK-coCRASH: Sanitizer's allocator is terminating the process
-// CHECK-rCRASH: realloc:
-// CHECK-rCRASH: Sanitizer's allocator is terminating the process
-// CHECK-mrCRASH: realloc-after-malloc:
-// CHECK-mrCRASH: Sanitizer's allocator is terminating the process
-// CHECK-nCRASH: new:
-// CHECK-nCRASH: Sanitizer's allocator is terminating the process
-// CHECK-nnCRASH: new-nothrow:
-// CHECK-nnCRASH: Sanitizer's allocator is terminating the process
-
-// CHECK-mNULL: malloc:
-// CHECK-mNULL: errno: 12
-// CHECK-mNULL: x: 0
-// CHECK-cNULL: calloc:
-// CHECK-cNULL: errno: 12
-// CHECK-cNULL: x: 0
-// CHECK-coNULL: calloc-overflow:
-// CHECK-coNULL: errno: 12
-// CHECK-coNULL: x: 0
-// CHECK-rNULL: realloc:
-// CHECK-rNULL: errno: 12
-// CHECK-rNULL: x: 0
-// CHECK-mrNULL: realloc-after-malloc:
-// CHECK-mrNULL: errno: 12
-// CHECK-mrNULL: x: 0
-// CHECK-nnNULL: new-nothrow:
-// CHECK-nnNULL: x: 0
diff --git a/test/msan/Linux/name_to_handle_at.cc b/test/msan/Linux/name_to_handle_at.cc
new file mode 100644
index 000000000000..0ff8d982f4f7
--- /dev/null
+++ b/test/msan/Linux/name_to_handle_at.cc
@@ -0,0 +1,28 @@
+// RUN: %clangxx_msan -std=c++11 -O0 -g %s -o %t && %run %t
+
+#include <assert.h>
+#include <fcntl.h>
+#include <sanitizer/msan_interface.h>
+#include <stdlib.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+int main(void) {
+ struct file_handle *handle = reinterpret_cast<struct file_handle *>(
+ malloc(sizeof(*handle) + MAX_HANDLE_SZ));
+ handle->handle_bytes = MAX_HANDLE_SZ;
+
+ int mount_id;
+ int res = name_to_handle_at(AT_FDCWD, "/bin/cat", handle, &mount_id, 0);
+ assert(!res);
+ __msan_check_mem_is_initialized(&mount_id, sizeof(mount_id));
+ __msan_check_mem_is_initialized(&handle->handle_bytes,
+ sizeof(handle->handle_bytes));
+ __msan_check_mem_is_initialized(&handle->handle_type,
+ sizeof(handle->handle_type));
+ __msan_check_mem_is_initialized(&handle->f_handle, handle->handle_bytes);
+
+ free(handle);
+ return 0;
+}
diff --git a/test/msan/Linux/sendmsg.cc b/test/msan/Linux/sendmsg.cc
index 4fc6c88cc5dd..91c3f64d7f21 100644
--- a/test/msan/Linux/sendmsg.cc
+++ b/test/msan/Linux/sendmsg.cc
@@ -1,10 +1,12 @@
// RUN: %clangxx_msan %s -DSEND -DPOISON -o %t && not %run %t 2>&1 | FileCheck %s --check-prefix=SEND
// RUN: %clangxx_msan %s -DSENDTO -DPOISON -o %t && not %run %t 2>&1 | FileCheck %s --check-prefix=SENDTO
// RUN: %clangxx_msan %s -DSENDMSG -DPOISON -o %t && not %run %t 2>&1 | FileCheck %s --check-prefix=SENDMSG
+// RUN: %clangxx_msan %s -DSENDMMSG -DPOISON -o %t && not %run %t 2>&1 | FileCheck %s --check-prefix=SENDMMSG
// RUN: %clangxx_msan %s -DSEND -o %t && %run %t 2>&1 | FileCheck %s --check-prefix=NEGATIVE
// RUN: %clangxx_msan %s -DSENDTO -o %t && %run %t 2>&1 | FileCheck %s --check-prefix=NEGATIVE
// RUN: %clangxx_msan %s -DSENDMSG -o %t && %run %t 2>&1 | FileCheck %s --check-prefix=NEGATIVE
+// RUN: %clangxx_msan %s -DSENDMMSG -o %t && %run %t 2>&1 | FileCheck %s --check-prefix=NEGATIVE
// RUN: %clangxx_msan %s -DSEND -DPOISON -o %t && \
// RUN: MSAN_OPTIONS=intercept_send=0 %run %t 2>&1 | FileCheck %s --check-prefix=NEGATIVE
@@ -12,6 +14,8 @@
// RUN: MSAN_OPTIONS=intercept_send=0 %run %t 2>&1 | FileCheck %s --check-prefix=NEGATIVE
// RUN: %clangxx_msan %s -DSENDMSG -DPOISON -o %t && \
// RUN: MSAN_OPTIONS=intercept_send=0 %run %t 2>&1 | FileCheck %s --check-prefix=NEGATIVE
+// RUN: %clangxx_msan %s -DSENDMMSG -DPOISON -o %t && \
+// RUN: MSAN_OPTIONS=intercept_send=0 %run %t 2>&1 | FileCheck %s --check-prefix=NEGATIVE
// UNSUPPORTED: android
@@ -20,54 +24,32 @@
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
-#include <netdb.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sanitizer/msan_interface.h>
const int kBufSize = 10;
-int sockfd;
+const int kRecvBufSize = 100;
+int sockfd[2];
int main() {
int ret;
+ int sent;
char buf[kBufSize] = {0};
- pthread_t client_thread;
- struct sockaddr_in serveraddr;
- struct sockaddr_in6 serveraddr6;
-
- memset(&serveraddr, 0, sizeof(serveraddr));
- serveraddr.sin_family = AF_INET;
- serveraddr.sin_addr.s_addr = htonl(INADDR_ANY);
- serveraddr.sin_port = 0;
- struct sockaddr *addr = (struct sockaddr *)&serveraddr;
- socklen_t addrlen = sizeof(serveraddr);
-
- sockfd = socket(addr->sa_family, SOCK_DGRAM, 0);
- if (sockfd <= 0) {
- // Try to fall-back to IPv6
- memset(&serveraddr6, 0, sizeof(serveraddr6));
- serveraddr6.sin6_family = AF_INET6;
- serveraddr6.sin6_addr = in6addr_any;
- serveraddr6.sin6_port = 0;
- addr = (struct sockaddr *)&serveraddr6;
- addrlen = sizeof(serveraddr6);
-
- sockfd = socket(addr->sa_family, SOCK_DGRAM, 0);
- }
- assert(sockfd > 0);
-
- bind(sockfd, addr, addrlen);
- getsockname(sockfd, addr, &addrlen);
+ char rbuf[kRecvBufSize];
+
+ ret = socketpair(AF_LOCAL, SOCK_DGRAM, 0, sockfd);
+ assert(!ret);
#if defined(POISON)
__msan_poison(buf + 7, 1);
#endif
-#if defined(SENDMSG)
+#if defined(SENDMSG) || defined(SENDMMSG)
struct iovec iov[2] = {{buf, 5}, {buf + 5, 5}};
struct msghdr msg;
- msg.msg_name = addr;
- msg.msg_namelen = addrlen;
+ msg.msg_name = nullptr;
+ msg.msg_namelen = 0;
msg.msg_iov = iov;
msg.msg_iovlen = 2;
msg.msg_control = 0;
@@ -75,20 +57,95 @@ int main() {
msg.msg_flags = 0;
#endif
+#if defined(SENDMMSG)
+ struct iovec iov0[1] = {{buf, 7}};
+ struct msghdr msg0;
+ msg0.msg_name = nullptr;
+ msg0.msg_namelen = 0;
+ msg0.msg_iov = iov0;
+ msg0.msg_iovlen = 1;
+ msg0.msg_control = 0;
+ msg0.msg_controllen = 0;
+ msg0.msg_flags = 0;
+
+ struct mmsghdr mmsg[2];
+ mmsg[0].msg_hdr = msg0; // good
+ mmsg[1].msg_hdr = msg; // poisoned
+#endif
+
#if defined(SEND)
- ret = connect(sockfd, addr, addrlen);
- assert(ret == 0);
- ret = send(sockfd, buf, kBufSize, 0);
+ sent = send(sockfd[0], buf, kBufSize, 0);
// SEND: Uninitialized bytes in __interceptor_send at offset 7 inside [{{.*}}, 10)
- assert(ret > 0);
+ assert(sent > 0);
+
+ ret = recv(sockfd[1], rbuf, kRecvBufSize, 0);
+ assert(ret == sent);
+ assert(__msan_test_shadow(rbuf, kRecvBufSize) == sent);
#elif defined(SENDTO)
- ret = sendto(sockfd, buf, kBufSize, 0, addr, addrlen);
+ sent = sendto(sockfd[0], buf, kBufSize, 0, nullptr, 0);
// SENDTO: Uninitialized bytes in __interceptor_sendto at offset 7 inside [{{.*}}, 10)
- assert(ret > 0);
+ assert(sent > 0);
+
+ struct sockaddr_storage ss;
+ socklen_t sslen = sizeof(ss);
+ ret = recvfrom(sockfd[1], rbuf, kRecvBufSize, 0, (struct sockaddr *)&ss,
+ &sslen);
+ assert(ret == sent);
+ assert(__msan_test_shadow(rbuf, kRecvBufSize) == sent);
+ assert(__msan_test_shadow(&ss, sizeof(ss)) == sslen);
#elif defined(SENDMSG)
- ret = sendmsg(sockfd, &msg, 0);
+ sent = sendmsg(sockfd[0], &msg, 0);
// SENDMSG: Uninitialized bytes in {{.*}} at offset 2 inside [{{.*}}, 5)
- assert(ret > 0);
+ assert(sent > 0);
+
+ struct iovec riov[2] = {{rbuf, 3}, {rbuf + 3, kRecvBufSize - 3}};
+ struct msghdr rmsg;
+ rmsg.msg_name = nullptr;
+ rmsg.msg_namelen = 0;
+ rmsg.msg_iov = riov;
+ rmsg.msg_iovlen = 2;
+ rmsg.msg_control = 0;
+ rmsg.msg_controllen = 0;
+ rmsg.msg_flags = 0;
+
+ ret = recvmsg(sockfd[1], &rmsg, 0);
+ assert(ret == sent);
+ assert(__msan_test_shadow(rbuf, kRecvBufSize) == sent);
+#elif defined(SENDMMSG)
+ sent = sendmmsg(sockfd[0], mmsg, 2, 0);
+ // SENDMMSG: Uninitialized bytes in {{.*}} at offset 2 inside [{{.*}}, 5)
+ assert(sent == 2);
+ if (ret >= 2)
+ assert(mmsg[1].msg_len > 0);
+
+ struct iovec riov[2] = {{rbuf + kRecvBufSize / 2, kRecvBufSize / 2}};
+ struct msghdr rmsg;
+ rmsg.msg_name = nullptr;
+ rmsg.msg_namelen = 0;
+ rmsg.msg_iov = riov;
+ rmsg.msg_iovlen = 1;
+ rmsg.msg_control = 0;
+ rmsg.msg_controllen = 0;
+ rmsg.msg_flags = 0;
+
+ struct iovec riov0[2] = {{rbuf, kRecvBufSize / 2}};
+ struct msghdr rmsg0;
+ rmsg0.msg_name = nullptr;
+ rmsg0.msg_namelen = 0;
+ rmsg0.msg_iov = riov0;
+ rmsg0.msg_iovlen = 1;
+ rmsg0.msg_control = 0;
+ rmsg0.msg_controllen = 0;
+ rmsg0.msg_flags = 0;
+
+ struct mmsghdr rmmsg[2];
+ rmmsg[0].msg_hdr = rmsg0;
+ rmmsg[1].msg_hdr = rmsg;
+
+ ret = recvmmsg(sockfd[1], rmmsg, 2, 0, nullptr);
+ assert(ret == sent);
+ assert(__msan_test_shadow(rbuf, kRecvBufSize) == 7);
+ assert(__msan_test_shadow(rbuf + kRecvBufSize / 2, kRecvBufSize / 2) == 10);
#endif
fprintf(stderr, "== done\n");
// NEGATIVE: == done
diff --git a/test/msan/check-handler.cc b/test/msan/check-handler.cc
new file mode 100644
index 000000000000..4721f8c3068e
--- /dev/null
+++ b/test/msan/check-handler.cc
@@ -0,0 +1,16 @@
+// RUN: %clangxx_msan -O0 -g %s -o %t && not %run %t 2>&1 | FileCheck %s
+
+// Verify that CHECK handler prints a stack on CHECK fail.
+
+#include <stdlib.h>
+
+int main(void) {
+ // Allocate chunk from the secondary allocator to trigger CHECK(IsALigned())
+ // in its free() path.
+ void *p = malloc(8 << 20);
+ free(reinterpret_cast<char*>(p) + 1);
+ // CHECK: MemorySanitizer: bad pointer
+ // CHECK: MemorySanitizer CHECK failed
+ // CHECK: #0
+ return 0;
+}
diff --git a/test/msan/coverage-levels.cc b/test/msan/coverage-levels.cc
index b881cecac7e9..5ca3b717d04f 100644
--- a/test/msan/coverage-levels.cc
+++ b/test/msan/coverage-levels.cc
@@ -1,14 +1,14 @@
// Test various levels of coverage
//
// RUN: %clangxx_msan -DINIT_VAR=1 -O1 -fsanitize-coverage=func %s -o %t
-// RUN: mkdir -p %T/coverage-levels
-// RUN: MSAN_OPTIONS=coverage=1:verbosity=1:coverage_dir=%T/coverage-levels %run %t 2>&1 | FileCheck %s --check-prefix=CHECK1 --check-prefix=CHECK_NOWARN
+// RUN: mkdir -p %t-dir
+// RUN: MSAN_OPTIONS=coverage=1:verbosity=1:coverage_dir=%t-dir %run %t 2>&1 | FileCheck %s --check-prefix=CHECK1 --check-prefix=CHECK_NOWARN
// RUN: %clangxx_msan -O1 -fsanitize-coverage=func %s -o %t
-// RUN: MSAN_OPTIONS=coverage=1:verbosity=1:coverage_dir=%T/coverage-levels not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK1 --check-prefix=CHECK_WARN
+// RUN: MSAN_OPTIONS=coverage=1:verbosity=1:coverage_dir=%t-dir not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK1 --check-prefix=CHECK_WARN
// RUN: %clangxx_msan -O1 -fsanitize-coverage=bb %s -o %t
-// RUN: MSAN_OPTIONS=coverage=1:verbosity=1:coverage_dir=%T/coverage-levels not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK2 --check-prefix=CHECK_WARN
+// RUN: MSAN_OPTIONS=coverage=1:verbosity=1:coverage_dir=%t-dir not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK2 --check-prefix=CHECK_WARN
// RUN: %clangxx_msan -O1 -fsanitize-coverage=edge %s -o %t
-// RUN: MSAN_OPTIONS=coverage=1:verbosity=1:coverage_dir=%T/coverage-levels not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK3 --check-prefix=CHECK_WARN
+// RUN: MSAN_OPTIONS=coverage=1:verbosity=1:coverage_dir=%t-dir not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK3 --check-prefix=CHECK_WARN
volatile int sink;
int main(int argc, char **argv) {
diff --git a/test/msan/dtls_test.c b/test/msan/dtls_test.c
index 49d95c44c1d8..b9021e0da1af 100644
--- a/test/msan/dtls_test.c
+++ b/test/msan/dtls_test.c
@@ -5,6 +5,9 @@
Regression test for a bug in msan/glibc integration,
see https://sourceware.org/bugzilla/show_bug.cgi?id=16291
and https://github.com/google/sanitizers/issues/547
+
+ XFAIL: FreeBSD
+ UNSUPPORTED: powerpc
*/
#ifndef BUILD_SO
diff --git a/test/msan/dtor-member.cc b/test/msan/dtor-member.cc
index 13a059947bca..bf20221a363b 100644
--- a/test/msan/dtor-member.cc
+++ b/test/msan/dtor-member.cc
@@ -7,7 +7,7 @@
// RUN: %clangxx_msan %s -O2 -fsanitize=memory -fsanitize-memory-use-after-dtor -o %t && MSAN_OPTIONS=poison_in_dtor=1 %run %t >%t.out 2>&1
// RUN: FileCheck %s < %t.out
-// RUN: %clangxx_msan %s -fsanitize=memory -o %t && MSAN_OPTIONS=poison_in_dtor=1 %run %t >%t.out 2>&1
+// RUN: %clangxx_msan %s -fsanitize=memory -fno-sanitize-memory-use-after-dtor -o %t && MSAN_OPTIONS=poison_in_dtor=1 %run %t >%t.out 2>&1
// RUN: FileCheck %s --check-prefix=CHECK-NO-FLAG < %t.out
// RUN: %clangxx_msan -fsanitize=memory -fsanitize-memory-use-after-dtor %s -o %t && MSAN_OPTIONS=poison_in_dtor=0 %run %t >%t.out 2>&1
diff --git a/test/msan/fgets_fputs.cc b/test/msan/fgets_fputs.cc
new file mode 100644
index 000000000000..1e96943980d6
--- /dev/null
+++ b/test/msan/fgets_fputs.cc
@@ -0,0 +1,47 @@
+// RUN: %clangxx_msan -g %s -o %t
+// RUN: %run %t
+// RUN: not %run %t 2 2>&1 | FileCheck %s --check-prefix=CHECK-FPUTS
+// RUN: not %run %t 3 3 2>&1 | FileCheck %s --check-prefix=CHECK-PUTS
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+int test_fgets() {
+ FILE *fp = fopen("/dev/zero", "r");
+ char c;
+
+ if (!fgets(&c, 1, fp))
+ return 1;
+
+ if (c == '1') // No error
+ return 2;
+
+ fclose(fp);
+ return 0;
+}
+
+int test_fputs() {
+ FILE *fp = fopen("/dev/null", "w");
+ char buf[2];
+ fputs(buf, fp); // BOOM
+ return fclose(fp);
+}
+
+void test_puts() {
+ char buf[2];
+ puts(buf); // BOOM
+}
+
+int main(int argc, char *argv[]) {
+ if (argc == 1)
+ test_fgets();
+ else if (argc == 2)
+ test_fputs();
+ else
+ test_puts();
+ return 0;
+}
+
+// CHECK-FPUTS: Uninitialized bytes in __interceptor_fputs at offset 0 inside
+// CHECK-PUTS: Uninitialized bytes in __interceptor_puts at offset 0 inside
diff --git a/test/msan/fstat.cc b/test/msan/fstat.cc
new file mode 100644
index 000000000000..83f97054cea7
--- /dev/null
+++ b/test/msan/fstat.cc
@@ -0,0 +1,15 @@
+// RUN: %clangxx_msan -O0 %s -o %t && %run %t
+
+#include <sys/stat.h>
+#include <stdlib.h>
+
+int main(void) {
+ struct stat st;
+ if (fstat(0, &st))
+ exit(1);
+
+ if (S_ISBLK(st.st_mode))
+ exit(0);
+
+ return 0;
+}
diff --git a/test/msan/getutent.cc b/test/msan/getutent.cc
index 36f9e1f1f7e3..b57101068ddd 100644
--- a/test/msan/getutent.cc
+++ b/test/msan/getutent.cc
@@ -1,14 +1,18 @@
// RUN: %clangxx_msan -O0 -g %s -o %t && %run %t
+#ifndef __FreeBSD__
#include <utmp.h>
+#endif
#include <utmpx.h>
#include <sanitizer/msan_interface.h>
int main(void) {
+#ifndef __FreeBSD__
setutent();
while (struct utmp *ut = getutent())
__msan_check_mem_is_initialized(ut, sizeof(*ut));
endutent();
+#endif
setutxent();
while (struct utmpx *utx = getutxent())
diff --git a/test/msan/iconv.cc b/test/msan/iconv.cc
index 7beb6a01877c..7713cb8e5f45 100644
--- a/test/msan/iconv.cc
+++ b/test/msan/iconv.cc
@@ -15,7 +15,7 @@ int main(void) {
char inbuf_[100];
strcpy(inbuf_, "sample text");
char outbuf_[100];
-#if defined(__FreeBSD__) || defined(__NetBSD__)
+#if defined(__NetBSD__)
// Some OSes expect the 2nd argument of iconv(3) to be of type const char **
const char *inbuf = inbuf_;
#else
diff --git a/test/msan/lit.cfg b/test/msan/lit.cfg
index cac260999877..550d04d0812b 100644
--- a/test/msan/lit.cfg
+++ b/test/msan/lit.cfg
@@ -29,7 +29,7 @@ config.substitutions.append( ("%clangxx_msan ", build_invocation(clang_msan_cxxf
# Default test suffixes.
config.suffixes = ['.c', '.cc', '.cpp']
-if config.host_os not in ['Linux', 'NetBSD']:
+if config.host_os not in ['Linux', 'NetBSD', 'FreeBSD']:
config.unsupported = True
# For mips64, mips64el we have forced store_context_size to 1 because these
diff --git a/test/msan/mmap.cc b/test/msan/mmap.cc
index 65d8beeefe3a..d83423735211 100644
--- a/test/msan/mmap.cc
+++ b/test/msan/mmap.cc
@@ -63,9 +63,13 @@ int main() {
const size_t kMapSize = 0x1000000000ULL;
#endif
int success_count = 0;
+ int flags = MAP_PRIVATE | MAP_ANONYMOUS;
+#if defined(MAP_NORESERVE)
+ flags |= MAP_NORESERVE;
+#endif
while (true) {
void *p = mmap(0, kMapSize, PROT_WRITE,
- MAP_PRIVATE | MAP_ANONYMOUS | MAP_NORESERVE, -1, 0);
+ flags, -1, 0);
printf("%p\n", p);
if (p == MAP_FAILED) {
assert(errno == ENOMEM);
diff --git a/test/msan/pthread_getattr_np_deadlock.cc b/test/msan/pthread_getattr_np_deadlock.cc
index 0f52280856cc..241caa2a211d 100644
--- a/test/msan/pthread_getattr_np_deadlock.cc
+++ b/test/msan/pthread_getattr_np_deadlock.cc
@@ -4,10 +4,20 @@
#include <assert.h>
#include <pthread.h>
+#if defined(__FreeBSD__)
+#include <pthread_np.h>
+#endif
void *ThreadFn(void *) {
pthread_attr_t attr;
+#if defined(__FreeBSD__)
+ // On FreeBSD it needs to allocate attr underlying memory
+ int res = pthread_attr_init(&attr);
+ assert(!res);
+ res = pthread_attr_get_np(pthread_self(), &attr);
+#else
int res = pthread_getattr_np(pthread_self(), &attr);
+#endif
assert(!res);
return 0;
}
diff --git a/test/msan/pthread_getname_np.cc b/test/msan/pthread_getname_np.cc
index ca27d8b6fd6c..e19b652a73c9 100644
--- a/test/msan/pthread_getname_np.cc
+++ b/test/msan/pthread_getname_np.cc
@@ -1,5 +1,7 @@
// RUN: %clangxx_msan -std=c++11 -O0 %s -o %t && %run %t
-// UNSUPPORTED: android, netbsd
+// The main goal is getting the pthread name back and
+// FreeBSD based do not support this feature
+// UNSUPPORTED: android, netbsd, freebsd
// Regression test for a deadlock in pthread_getattr_np
@@ -10,12 +12,22 @@
#include <stdio.h>
+// Stall child thread on this lock to make sure it doesn't finish
+// before the end of the pthread_getname_np() / pthread_setname_np() tests.
+static pthread_mutex_t lock;
+
void *ThreadFn(void *) {
+ pthread_mutex_lock (&lock);
+ pthread_mutex_unlock (&lock);
return nullptr;
}
int main(void) {
pthread_t t;
+
+ pthread_mutex_init (&lock, NULL);
+ pthread_mutex_lock (&lock);
+
int res = pthread_create(&t, 0, ThreadFn, 0);
assert(!res);
@@ -28,6 +40,8 @@ int main(void) {
assert(!res);
assert(strcmp(buf, kMyThreadName) == 0);
+ pthread_mutex_unlock (&lock);
+
res = pthread_join(t, 0);
assert(!res);
return 0;
diff --git a/test/msan/pvalloc.cc b/test/msan/pvalloc.cc
deleted file mode 100644
index 7c406df79bb1..000000000000
--- a/test/msan/pvalloc.cc
+++ /dev/null
@@ -1,43 +0,0 @@
-// RUN: %clangxx_msan -O0 %s -o %t
-// RUN: MSAN_OPTIONS=allocator_may_return_null=0 not %run %t m1 2>&1 | FileCheck %s
-// RUN: MSAN_OPTIONS=allocator_may_return_null=1 %run %t m1 2>&1
-// RUN: MSAN_OPTIONS=allocator_may_return_null=0 not %run %t psm1 2>&1 | FileCheck %s
-// RUN: MSAN_OPTIONS=allocator_may_return_null=1 %run %t psm1 2>&1
-
-// UNSUPPORTED: win32, freebsd, netbsd
-
-// Checks that pvalloc overflows are caught. If the allocator is allowed to
-// return null, the errno should be set to ENOMEM.
-
-#include <assert.h>
-#include <errno.h>
-#include <malloc.h>
-#include <stdint.h>
-#include <string.h>
-#include <unistd.h>
-
-int main(int argc, char *argv[]) {
- void *p;
- size_t page_size;
-
- assert(argc == 2);
-
- page_size = sysconf(_SC_PAGESIZE);
- // Check that the page size is a power of two.
- assert((page_size & (page_size - 1)) == 0);
-
- if (!strcmp(argv[1], "m1")) {
- p = pvalloc((uintptr_t)-1);
- assert(!p);
- assert(errno == ENOMEM);
- }
- if (!strcmp(argv[1], "psm1")) {
- p = pvalloc((uintptr_t)-(page_size - 1));
- assert(!p);
- assert(errno == ENOMEM);
- }
-
- return 0;
-}
-
-// CHECK: MemorySanitizer's allocator is terminating the process
diff --git a/test/msan/scoped-interceptors.cc b/test/msan/scoped-interceptors.cc
new file mode 100644
index 000000000000..fc7d4578482b
--- /dev/null
+++ b/test/msan/scoped-interceptors.cc
@@ -0,0 +1,52 @@
+// RUN: %clangxx_msan %s -o %t
+// RUN: %run %t --disable-checks 0 2>&1 | FileCheck --check-prefix=DISABLED --allow-empty %s
+// RUN: %run %t --disable-checks 1 2>&1 | FileCheck --check-prefix=DISABLED --allow-empty %s
+// RUN: %run %t --disable-checks 2 2>&1 | FileCheck --check-prefix=DISABLED --allow-empty %s
+// RUN: %run %t --disable-checks 3 2>&1 | FileCheck --check-prefix=DISABLED --allow-empty %s
+// RUN: not %run %t --reenable-checks 0 2>&1 | FileCheck --check-prefix=CASE-0 %s
+// RUN: not %run %t --reenable-checks 1 2>&1 | FileCheck --check-prefix=CASE-1 %s
+// RUN: not %run %t --reenable-checks 2 2>&1 | FileCheck --check-prefix=CASE-2 %s
+// RUN: not %run %t --reenable-checks 3 2>&1 | FileCheck --check-prefix=CASE-3 %s
+
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sanitizer/msan_interface.h>
+
+int main(int argc, char *argv[]) {
+ assert(argc == 3);
+ __msan_scoped_disable_interceptor_checks();
+ if (strcmp(argv[1], "--reenable-checks") == 0)
+ __msan_scoped_enable_interceptor_checks();
+
+ char uninit[7];
+ switch (argv[2][0]) {
+ case '0': {
+ char *copy = strndup(uninit, sizeof(uninit)); // BOOM
+ free(copy);
+ break;
+ // CASE-0: Uninitialized bytes in __interceptor_strndup
+ }
+ case '1': {
+ puts(uninit); // BOOM
+ puts(uninit); // Ensure previous call did not enable interceptor checks.
+ break;
+ // CASE-1: Uninitialized bytes in __interceptor_puts
+ }
+ case '2': {
+ int cmp = memcmp(uninit, uninit, sizeof(uninit)); // BOOM
+ break;
+ // CASE-2: Uninitialized bytes in __interceptor_memcmp
+ }
+ case '3': {
+ size_t len = strlen(uninit); // BOOM
+ break;
+ // CASE-3: Uninitialized bytes in __interceptor_strlen
+ }
+ default: assert(0);
+ }
+ // DISABLED-NOT: Uninitialized bytes
+ return 0;
+}
+
diff --git a/test/msan/strlen_of_shadow.cc b/test/msan/strlen_of_shadow.cc
index b9cf5f065d2d..718cc08dc1fd 100644
--- a/test/msan/strlen_of_shadow.cc
+++ b/test/msan/strlen_of_shadow.cc
@@ -2,6 +2,8 @@
// Check that strlen() and similar intercepted functions can be called on shadow
// memory.
+// The mem_to_shadow's part might need rework
+// XFAIL: freebsd
#include <assert.h>
#include <stdint.h>
diff --git a/test/msan/textdomain.cc b/test/msan/textdomain.cc
index 760debd68c33..478b0993f837 100644
--- a/test/msan/textdomain.cc
+++ b/test/msan/textdomain.cc
@@ -1,4 +1,6 @@
// RUN: %clangxx_msan -O0 -g %s -o %t && %run %t
+// textdomain() is not a part of libc on FreeBSD and NetBSD.
+// UNSUPPORTED: netbsd, freebsd
#include <libintl.h>
#include <stdio.h>
diff --git a/test/msan/tls_reuse.cc b/test/msan/tls_reuse.cc
index 78a328fa3ce0..9c2ee975cb57 100644
--- a/test/msan/tls_reuse.cc
+++ b/test/msan/tls_reuse.cc
@@ -1,6 +1,7 @@
// RUN: %clangxx_msan -O0 %s -o %t && %run %t
// Check that when TLS block is reused between threads, its shadow is cleaned.
+// XFAIL: freebsd
#include <pthread.h>
#include <stdio.h>
diff --git a/test/msan/tsearch.cc b/test/msan/tsearch.cc
index 0d8ee8f35b25..50a2efb31fad 100644
--- a/test/msan/tsearch.cc
+++ b/test/msan/tsearch.cc
@@ -1,7 +1,7 @@
// RUN: %clangxx_msan -O0 -g %s -o %t && %run %t
// tdestroy is a GNU extension
-// UNSUPPORTED: netbsd
+// UNSUPPORTED: netbsd, freebsd
#include <assert.h>
#include <search.h>
diff --git a/test/msan/tzset.cc b/test/msan/tzset.cc
index 05915e047e15..86805cd56c5d 100644
--- a/test/msan/tzset.cc
+++ b/test/msan/tzset.cc
@@ -1,4 +1,5 @@
// RUN: %clangxx_msan -O0 %s -o %t && %run %t
+// XFAIL: freebsd
#include <stdlib.h>
#include <string.h>
diff --git a/test/msan/use-after-dtor.cc b/test/msan/use-after-dtor.cc
index 6c751a14f377..45f4dcd69b78 100644
--- a/test/msan/use-after-dtor.cc
+++ b/test/msan/use-after-dtor.cc
@@ -1,14 +1,17 @@
// RUN: %clangxx_msan %s -fsanitize=memory -fsanitize-memory-use-after-dtor -o %t && MSAN_OPTIONS=poison_in_dtor=1 not %run %t >%t.out 2>&1
-// RUN: FileCheck %s < %t.out
+// RUN: FileCheck %s --check-prefix=CHECK-UAD < %t.out
// RUN: %clangxx_msan %s -O1 -fsanitize=memory -fsanitize-memory-use-after-dtor -o %t && MSAN_OPTIONS=poison_in_dtor=1 not %run %t >%t.out 2>&1
-// RUN: FileCheck %s < %t.out
+// RUN: FileCheck %s --check-prefix=CHECK-UAD < %t.out
// RUN: %clangxx_msan %s -O2 -fsanitize=memory -fsanitize-memory-use-after-dtor -o %t && MSAN_OPTIONS=poison_in_dtor=1 not %run %t >%t.out 2>&1
-// RUN: FileCheck %s < %t.out
+// RUN: FileCheck %s --check-prefix=CHECK-UAD < %t.out
// RUN: %clangxx_msan %s -O1 -fsanitize=memory -fsanitize-memory-use-after-dtor -fsanitize-memory-track-origins -o %t && MSAN_OPTIONS=poison_in_dtor=1 not %run %t >%t.out 2>&1
-// RUN: FileCheck %s --check-prefix=CHECK-ORIGINS < %t.out
+// RUN: FileCheck %s --check-prefixes=CHECK-UAD,CHECK-ORIGINS < %t.out
+
+// RUN: %clangxx_msan %s -fno-sanitize-memory-use-after-dtor -o %t && MSAN_OPTIONS=poison_in_dtor=1 not %run %t > %t.out 2>&1
+// RUN: FileCheck %s --check-prefix=CHECK-UAD-OFF < %t.out
#include <sanitizer/msan_interface.h>
#include <assert.h>
@@ -32,14 +35,16 @@ int main() {
Simple *s = new(&buf) Simple();
s->~Simple();
+ fprintf(stderr, "\n"); // Need output to parse for CHECK-UAD-OFF case
return s->x_;
- // CHECK: WARNING: MemorySanitizer: use-of-uninitialized-value
- // CHECK: {{#0 0x.* in main.*use-after-dtor.cc:}}[[@LINE-3]]
+ // CHECK-UAD: WARNING: MemorySanitizer: use-of-uninitialized-value
+ // CHECK-UAD: {{#0 0x.* in main.*use-after-dtor.cc:}}[[@LINE-3]]
// CHECK-ORIGINS: Memory was marked as uninitialized
// CHECK-ORIGINS: {{#0 0x.* in __sanitizer_dtor_callback}}
// CHECK-ORIGINS: {{#1 0x.* in Simple::~Simple}}
- // CHECK: SUMMARY: MemorySanitizer: use-of-uninitialized-value {{.*main}}
+ // CHECK-UAD: SUMMARY: MemorySanitizer: use-of-uninitialized-value {{.*main}}
+ // CHECK-UAD-OFF-NOT: SUMMARY: MemorySanitizer: use-of-uninitialized-value
}
diff --git a/test/msan/vector_div.cc b/test/msan/vector_div.cc
new file mode 100644
index 000000000000..4ca2369d63e6
--- /dev/null
+++ b/test/msan/vector_div.cc
@@ -0,0 +1,17 @@
+// Regression test for https://bugs.llvm.org/show_bug.cgi?id=37523
+
+// RUN: %clangxx_msan -O0 %s -o %t && %run %t
+// RUN: %clangxx_msan -O3 %s -o %t && %run %t
+// REQUIRES: x86_64-target-arch
+
+#include <assert.h>
+#include <emmintrin.h>
+
+int main() {
+ volatile int scale = 5;
+ volatile auto zz = _mm_div_ps(_mm_set1_ps(255), _mm_set1_ps(scale));
+ assert(zz[0] == 51);
+ assert(zz[1] == 51);
+ assert(zz[2] == 51);
+ assert(zz[3] == 51);
+}
diff --git a/test/msan/wcsxfrm.cc b/test/msan/wcsxfrm.cc
new file mode 100644
index 000000000000..f13c5d3969a8
--- /dev/null
+++ b/test/msan/wcsxfrm.cc
@@ -0,0 +1,30 @@
+// RUN: %clangxx_msan -O0 -g %s -o %t && not %run %t
+
+#include <assert.h>
+#include <locale.h>
+#include <sanitizer/msan_interface.h>
+#include <stdlib.h>
+#include <wchar.h>
+
+int main(void) {
+ wchar_t q[10];
+ size_t n = wcsxfrm(q, L"abcdef", sizeof(q) / sizeof(wchar_t));
+ assert(n < sizeof(q));
+ __msan_check_mem_is_initialized(q, (n + 1) * sizeof(wchar_t));
+
+ locale_t loc = newlocale(LC_ALL_MASK, "", (locale_t)0);
+
+ __msan_poison(&q, sizeof(q));
+ n = wcsxfrm_l(q, L"qwerty", sizeof(q) / sizeof(wchar_t), loc);
+ assert(n < sizeof(q));
+ __msan_check_mem_is_initialized(q, (n + 1) * sizeof(wchar_t));
+
+ q[0] = 'A';
+ q[1] = '\x00';
+ __msan_poison(&q, sizeof(q));
+ wcsxfrm(NULL, q, 0);
+
+ // CHECK: WARNING: MemorySanitizer: use-of-uninitialized-value
+ // CHECK: in main {{.*}}wcsxfrm.cc:25
+ return 0;
+}
diff --git a/test/profile/Inputs/instrprof-dlopen-dlclose-main.c b/test/profile/Inputs/instrprof-dlopen-dlclose-main.c
new file mode 100644
index 000000000000..3f4a4f6cc6a6
--- /dev/null
+++ b/test/profile/Inputs/instrprof-dlopen-dlclose-main.c
@@ -0,0 +1,86 @@
+#include <dlfcn.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+int main(int argc, char *argv[]) {
+ dlerror();
+ void *f1_handle = dlopen("func.shared", RTLD_LAZY | RTLD_GLOBAL);
+ if (f1_handle == NULL) {
+ fprintf(stderr, "unable to open 'func.shared': %s\n", dlerror());
+ return EXIT_FAILURE;
+ }
+
+ void (*func)(void) = (void (*)(void))dlsym(f1_handle, "func");
+ if (func == NULL) {
+ fprintf(stderr, "unable to lookup symbol 'func': %s\n", dlerror());
+ return EXIT_FAILURE;
+ }
+
+ dlerror();
+ void *f2_handle = dlopen("func2.shared", RTLD_LAZY | RTLD_GLOBAL);
+ if (f2_handle == NULL) {
+ fprintf(stderr, "unable to open 'func2.shared': %s\n", dlerror());
+ return EXIT_FAILURE;
+ }
+
+ void (*func2)(void) = (void (*)(void))dlsym(f2_handle, "func2");
+ if (func2 == NULL) {
+ fprintf(stderr, "unable to lookup symbol 'func2': %s\n", dlerror());
+ return EXIT_FAILURE;
+ }
+ func2();
+
+#ifdef USE_LIB3
+ void *f3_handle = dlopen("func3.shared", RTLD_LAZY | RTLD_GLOBAL);
+ if (f3_handle == NULL) {
+ fprintf(stderr, "unable to open 'func3.shared': %s\n", dlerror());
+ return EXIT_FAILURE;
+ }
+
+ void (*func3)(void) = (void (*)(void))dlsym(f3_handle, "func3");
+ if (func3 == NULL) {
+ fprintf(stderr, "unable to lookup symbol 'func3': %s\n", dlerror());
+ return EXIT_FAILURE;
+ }
+ func3();
+#endif
+
+ dlerror();
+ void (*gcov_flush1)() = (void (*)())dlsym(f1_handle, "__gcov_flush");
+ if (gcov_flush1 == NULL) {
+ fprintf(stderr, "unable to find __gcov_flush in func.shared': %s\n", dlerror());
+ return EXIT_FAILURE;
+ }
+
+ dlerror();
+ void (*gcov_flush2)() = (void (*)())dlsym(f2_handle, "__gcov_flush");
+ if (gcov_flush2 == NULL) {
+ fprintf(stderr, "unable to find __gcov_flush in func2.shared': %s\n", dlerror());
+ return EXIT_FAILURE;
+ }
+
+ if (gcov_flush1 == gcov_flush2) {
+ fprintf(stderr, "Same __gcov_flush found in func.shared and func2.shared\n");
+ return EXIT_FAILURE;
+ }
+
+ dlerror();
+ if (dlclose(f2_handle) != 0) {
+ fprintf(stderr, "unable to close 'func2.shared': %s\n", dlerror());
+ return EXIT_FAILURE;
+ }
+
+ func();
+
+ int g1 = 0;
+ int g2 = 0;
+ int n = 10;
+
+ if (n % 5 == 0)
+ g1++;
+ else
+ g2++;
+
+ return EXIT_SUCCESS;
+}
+
diff --git a/test/profile/Inputs/instrprof-dlopen-dlclose-main.c.gcov b/test/profile/Inputs/instrprof-dlopen-dlclose-main.c.gcov
new file mode 100644
index 000000000000..acb2076fd763
--- /dev/null
+++ b/test/profile/Inputs/instrprof-dlopen-dlclose-main.c.gcov
@@ -0,0 +1,91 @@
+// CHECK: -: 0:Source:{{.*}}Inputs/instrprof-dlopen-dlclose-main.c
+// CHECK-NEXT: -: 0:Graph:instrprof-dlopen-dlclose-main.gcno
+// CHECK-NEXT: -: 0:Data:instrprof-dlopen-dlclose-main.gcda
+// CHECK-NEXT: -: 0:Runs:1
+// CHECK-NEXT: -: 0:Programs:1
+// CHECK-NEXT: -: 1:#include <dlfcn.h>
+// CHECK-NEXT: -: 2:#include <stdio.h>
+// CHECK-NEXT: -: 3:#include <stdlib.h>
+// CHECK-NEXT: -: 4:
+// CHECK-NEXT: -: 5:int main(int argc, char *argv[]) {
+// CHECK-NEXT: 1: 6: dlerror();
+// CHECK-NEXT: 1: 7: void *f1_handle = dlopen("func.shared", RTLD_LAZY | RTLD_GLOBAL);
+// CHECK-NEXT: 1: 8: if (f1_handle == NULL) {
+// CHECK-NEXT: #####: 9: fprintf(stderr, "unable to open 'func.shared': %s\n", dlerror());
+// CHECK-NEXT: #####: 10: return EXIT_FAILURE;
+// CHECK-NEXT: -: 11: }
+// CHECK-NEXT: -: 12:
+// CHECK-NEXT: 1: 13: void (*func)(void) = (void (*)(void))dlsym(f1_handle, "func");
+// CHECK-NEXT: 1: 14: if (func == NULL) {
+// CHECK-NEXT: #####: 15: fprintf(stderr, "unable to lookup symbol 'func': %s\n", dlerror());
+// CHECK-NEXT: #####: 16: return EXIT_FAILURE;
+// CHECK-NEXT: -: 17: }
+// CHECK-NEXT: -: 18:
+// CHECK-NEXT: 1: 19: dlerror();
+// CHECK-NEXT: 1: 20: void *f2_handle = dlopen("func2.shared", RTLD_LAZY | RTLD_GLOBAL);
+// CHECK-NEXT: 1: 21: if (f2_handle == NULL) {
+// CHECK-NEXT: #####: 22: fprintf(stderr, "unable to open 'func2.shared': %s\n", dlerror());
+// CHECK-NEXT: #####: 23: return EXIT_FAILURE;
+// CHECK-NEXT: -: 24: }
+// CHECK-NEXT: -: 25:
+// CHECK-NEXT: 1: 26: void (*func2)(void) = (void (*)(void))dlsym(f2_handle, "func2");
+// CHECK-NEXT: 1: 27: if (func2 == NULL) {
+// CHECK-NEXT: #####: 28: fprintf(stderr, "unable to lookup symbol 'func2': %s\n", dlerror());
+// CHECK-NEXT: #####: 29: return EXIT_FAILURE;
+// CHECK-NEXT: -: 30: }
+// CHECK-NEXT: 1: 31: func2();
+// CHECK-NEXT: -: 32:
+// CHECK-NEXT: -: 33:#ifdef USE_LIB3
+// CHECK-NEXT: -: 34: void *f3_handle = dlopen("func3.shared", RTLD_LAZY | RTLD_GLOBAL);
+// CHECK-NEXT: -: 35: if (f3_handle == NULL) {
+// CHECK-NEXT: -: 36: fprintf(stderr, "unable to open 'func3.shared': %s\n", dlerror());
+// CHECK-NEXT: -: 37: return EXIT_FAILURE;
+// CHECK-NEXT: -: 38: }
+// CHECK-NEXT: -: 39:
+// CHECK-NEXT: -: 40: void (*func3)(void) = (void (*)(void))dlsym(f3_handle, "func3");
+// CHECK-NEXT: -: 41: if (func3 == NULL) {
+// CHECK-NEXT: -: 42: fprintf(stderr, "unable to lookup symbol 'func3': %s\n", dlerror());
+// CHECK-NEXT: -: 43: return EXIT_FAILURE;
+// CHECK-NEXT: -: 44: }
+// CHECK-NEXT: -: 45: func3();
+// CHECK-NEXT: -: 46:#endif
+// CHECK-NEXT: -: 47:
+// CHECK-NEXT: 1: 48: dlerror();
+// CHECK-NEXT: 1: 49: void (*gcov_flush1)() = (void (*)())dlsym(f1_handle, "__gcov_flush");
+// CHECK-NEXT: 1: 50: if (gcov_flush1 == NULL) {
+// CHECK-NEXT: #####: 51: fprintf(stderr, "unable to find __gcov_flush in func.shared': %s\n", dlerror());
+// CHECK-NEXT: #####: 52: return EXIT_FAILURE;
+// CHECK-NEXT: -: 53: }
+// CHECK-NEXT: -: 54:
+// CHECK-NEXT: 1: 55: dlerror();
+// CHECK-NEXT: 1: 56: void (*gcov_flush2)() = (void (*)())dlsym(f2_handle, "__gcov_flush");
+// CHECK-NEXT: 1: 57: if (gcov_flush2 == NULL) {
+// CHECK-NEXT: #####: 58: fprintf(stderr, "unable to find __gcov_flush in func2.shared': %s\n", dlerror());
+// CHECK-NEXT: #####: 59: return EXIT_FAILURE;
+// CHECK-NEXT: -: 60: }
+// CHECK-NEXT: -: 61:
+// CHECK-NEXT: 1: 62: if (gcov_flush1 == gcov_flush2) {
+// CHECK-NEXT: #####: 63: fprintf(stderr, "Same __gcov_flush found in func.shared and func2.shared\n");
+// CHECK-NEXT: #####: 64: return EXIT_FAILURE;
+// CHECK-NEXT: -: 65: }
+// CHECK-NEXT: -: 66:
+// CHECK-NEXT: 1: 67: dlerror();
+// CHECK-NEXT: 1: 68: if (dlclose(f2_handle) != 0) {
+// CHECK-NEXT: #####: 69: fprintf(stderr, "unable to close 'func2.shared': %s\n", dlerror());
+// CHECK-NEXT: #####: 70: return EXIT_FAILURE;
+// CHECK-NEXT: -: 71: }
+// CHECK-NEXT: -: 72:
+// CHECK-NEXT: 1: 73: func();
+// CHECK-NEXT: -: 74:
+// CHECK-NEXT: 1: 75: int g1 = 0;
+// CHECK-NEXT: 1: 76: int g2 = 0;
+// CHECK-NEXT: 1: 77: int n = 10;
+// CHECK-NEXT: -: 78:
+// CHECK-NEXT: 1: 79: if (n % 5 == 0)
+// CHECK-NEXT: 1: 80: g1++;
+// CHECK-NEXT: -: 81: else
+// CHECK-NEXT: #####: 82: g2++;
+// CHECK-NEXT: -: 83:
+// CHECK-NEXT: 1: 84: return EXIT_SUCCESS;
+// CHECK-NEXT: 1: 85:}
+// CHECK-NEXT: -: 86:
diff --git a/test/profile/Inputs/instrprof-dlopen-dlclose-main_three-libs.c.gcov b/test/profile/Inputs/instrprof-dlopen-dlclose-main_three-libs.c.gcov
new file mode 100644
index 000000000000..97eef4c3b905
--- /dev/null
+++ b/test/profile/Inputs/instrprof-dlopen-dlclose-main_three-libs.c.gcov
@@ -0,0 +1,91 @@
+// CHECK: -: 0:Source:{{.*}}Inputs/instrprof-dlopen-dlclose-main.c
+// CHECK-NEXT: -: 0:Graph:instrprof-dlopen-dlclose-main.gcno
+// CHECK-NEXT: -: 0:Data:instrprof-dlopen-dlclose-main.gcda
+// CHECK-NEXT: -: 0:Runs:1
+// CHECK-NEXT: -: 0:Programs:1
+// CHECK-NEXT: -: 1:#include <dlfcn.h>
+// CHECK-NEXT: -: 2:#include <stdio.h>
+// CHECK-NEXT: -: 3:#include <stdlib.h>
+// CHECK-NEXT: -: 4:
+// CHECK-NEXT: -: 5:int main(int argc, char *argv[]) {
+// CHECK-NEXT: 1: 6: dlerror();
+// CHECK-NEXT: 1: 7: void *f1_handle = dlopen("func.shared", RTLD_LAZY | RTLD_GLOBAL);
+// CHECK-NEXT: 1: 8: if (f1_handle == NULL) {
+// CHECK-NEXT: #####: 9: fprintf(stderr, "unable to open 'func.shared': %s\n", dlerror());
+// CHECK-NEXT: #####: 10: return EXIT_FAILURE;
+// CHECK-NEXT: -: 11: }
+// CHECK-NEXT: -: 12:
+// CHECK-NEXT: 1: 13: void (*func)(void) = (void (*)(void))dlsym(f1_handle, "func");
+// CHECK-NEXT: 1: 14: if (func == NULL) {
+// CHECK-NEXT: #####: 15: fprintf(stderr, "unable to lookup symbol 'func': %s\n", dlerror());
+// CHECK-NEXT: #####: 16: return EXIT_FAILURE;
+// CHECK-NEXT: -: 17: }
+// CHECK-NEXT: -: 18:
+// CHECK-NEXT: 1: 19: dlerror();
+// CHECK-NEXT: 1: 20: void *f2_handle = dlopen("func2.shared", RTLD_LAZY | RTLD_GLOBAL);
+// CHECK-NEXT: 1: 21: if (f2_handle == NULL) {
+// CHECK-NEXT: #####: 22: fprintf(stderr, "unable to open 'func2.shared': %s\n", dlerror());
+// CHECK-NEXT: #####: 23: return EXIT_FAILURE;
+// CHECK-NEXT: -: 24: }
+// CHECK-NEXT: -: 25:
+// CHECK-NEXT: 1: 26: void (*func2)(void) = (void (*)(void))dlsym(f2_handle, "func2");
+// CHECK-NEXT: 1: 27: if (func2 == NULL) {
+// CHECK-NEXT: #####: 28: fprintf(stderr, "unable to lookup symbol 'func2': %s\n", dlerror());
+// CHECK-NEXT: #####: 29: return EXIT_FAILURE;
+// CHECK-NEXT: -: 30: }
+// CHECK-NEXT: 1: 31: func2();
+// CHECK-NEXT: -: 32:
+// CHECK-NEXT: -: 33:#ifdef USE_LIB3
+// CHECK-NEXT: 1: 34: void *f3_handle = dlopen("func3.shared", RTLD_LAZY | RTLD_GLOBAL);
+// CHECK-NEXT: 1: 35: if (f3_handle == NULL) {
+// CHECK-NEXT: #####: 36: fprintf(stderr, "unable to open 'func3.shared': %s\n", dlerror());
+// CHECK-NEXT: #####: 37: return EXIT_FAILURE;
+// CHECK-NEXT: -: 38: }
+// CHECK-NEXT: -: 39:
+// CHECK-NEXT: 1: 40: void (*func3)(void) = (void (*)(void))dlsym(f3_handle, "func3");
+// CHECK-NEXT: 1: 41: if (func3 == NULL) {
+// CHECK-NEXT: #####: 42: fprintf(stderr, "unable to lookup symbol 'func3': %s\n", dlerror());
+// CHECK-NEXT: #####: 43: return EXIT_FAILURE;
+// CHECK-NEXT: -: 44: }
+// CHECK-NEXT: 1: 45: func3();
+// CHECK-NEXT: -: 46:#endif
+// CHECK-NEXT: -: 47:
+// CHECK-NEXT: 1: 48: dlerror();
+// CHECK-NEXT: 1: 49: void (*gcov_flush1)() = (void (*)())dlsym(f1_handle, "__gcov_flush");
+// CHECK-NEXT: 1: 50: if (gcov_flush1 == NULL) {
+// CHECK-NEXT: #####: 51: fprintf(stderr, "unable to find __gcov_flush in func.shared': %s\n", dlerror());
+// CHECK-NEXT: #####: 52: return EXIT_FAILURE;
+// CHECK-NEXT: -: 53: }
+// CHECK-NEXT: -: 54:
+// CHECK-NEXT: 1: 55: dlerror();
+// CHECK-NEXT: 1: 56: void (*gcov_flush2)() = (void (*)())dlsym(f2_handle, "__gcov_flush");
+// CHECK-NEXT: 1: 57: if (gcov_flush2 == NULL) {
+// CHECK-NEXT: #####: 58: fprintf(stderr, "unable to find __gcov_flush in func2.shared': %s\n", dlerror());
+// CHECK-NEXT: #####: 59: return EXIT_FAILURE;
+// CHECK-NEXT: -: 60: }
+// CHECK-NEXT: -: 61:
+// CHECK-NEXT: 1: 62: if (gcov_flush1 == gcov_flush2) {
+// CHECK-NEXT: #####: 63: fprintf(stderr, "Same __gcov_flush found in func.shared and func2.shared\n");
+// CHECK-NEXT: #####: 64: return EXIT_FAILURE;
+// CHECK-NEXT: -: 65: }
+// CHECK-NEXT: -: 66:
+// CHECK-NEXT: 1: 67: dlerror();
+// CHECK-NEXT: 1: 68: if (dlclose(f2_handle) != 0) {
+// CHECK-NEXT: #####: 69: fprintf(stderr, "unable to close 'func2.shared': %s\n", dlerror());
+// CHECK-NEXT: #####: 70: return EXIT_FAILURE;
+// CHECK-NEXT: -: 71: }
+// CHECK-NEXT: -: 72:
+// CHECK-NEXT: 1: 73: func();
+// CHECK-NEXT: -: 74:
+// CHECK-NEXT: 1: 75: int g1 = 0;
+// CHECK-NEXT: 1: 76: int g2 = 0;
+// CHECK-NEXT: 1: 77: int n = 10;
+// CHECK-NEXT: -: 78:
+// CHECK-NEXT: 1: 79: if (n % 5 == 0)
+// CHECK-NEXT: 1: 80: g1++;
+// CHECK-NEXT: -: 81: else
+// CHECK-NEXT: #####: 82: g2++;
+// CHECK-NEXT: -: 83:
+// CHECK-NEXT: 1: 84: return EXIT_SUCCESS;
+// CHECK-NEXT: 1: 85:}
+// CHECK-NEXT: -: 86:
diff --git a/test/profile/Inputs/instrprof-dlopen-func.c b/test/profile/Inputs/instrprof-dlopen-func.c
index f2de3883535a..9a56e4976570 100644
--- a/test/profile/Inputs/instrprof-dlopen-func.c
+++ b/test/profile/Inputs/instrprof-dlopen-func.c
@@ -1 +1 @@
-void func(int K) { if (K) {} }
+void func(int K) {}
diff --git a/test/profile/Inputs/instrprof-dlopen-func.c.gcov b/test/profile/Inputs/instrprof-dlopen-func.c.gcov
new file mode 100644
index 000000000000..3af4ec94a1b0
--- /dev/null
+++ b/test/profile/Inputs/instrprof-dlopen-func.c.gcov
@@ -0,0 +1,6 @@
+// CHECK: -: 0:Source:{{.*}}Inputs/instrprof-dlopen-func.c
+// CHECK-NEXT: -: 0:Graph:instrprof-dlopen-func.gcno
+// CHECK-NEXT: -: 0:Data:instrprof-dlopen-func.gcda
+// CHECK-NEXT: -: 0:Runs:1
+// CHECK-NEXT: -: 0:Programs:1
+// CHECK-NEXT: 1: 1:void func(int K) {}
diff --git a/test/profile/Inputs/instrprof-dlopen-func2.c b/test/profile/Inputs/instrprof-dlopen-func2.c
index d4d93dc0b256..ab62f14952c7 100644
--- a/test/profile/Inputs/instrprof-dlopen-func2.c
+++ b/test/profile/Inputs/instrprof-dlopen-func2.c
@@ -1 +1 @@
-void func2(int K) { if (K) {} }
+void func2(int K) {}
diff --git a/test/profile/Inputs/instrprof-dlopen-func2.c.gcov b/test/profile/Inputs/instrprof-dlopen-func2.c.gcov
new file mode 100644
index 000000000000..7101f74b938d
--- /dev/null
+++ b/test/profile/Inputs/instrprof-dlopen-func2.c.gcov
@@ -0,0 +1,6 @@
+// CHECK: -: 0:Source:{{.*}}Inputs/instrprof-dlopen-func2.c
+// CHECK-NEXT: -: 0:Graph:instrprof-dlopen-func2.gcno
+// CHECK-NEXT: -: 0:Data:instrprof-dlopen-func2.gcda
+// CHECK-NEXT: -: 0:Runs:1
+// CHECK-NEXT: -: 0:Programs:1
+// CHECK-NEXT: 1: 1:void func2(int K) {}
diff --git a/test/profile/Inputs/instrprof-dlopen-func3.c b/test/profile/Inputs/instrprof-dlopen-func3.c
new file mode 100644
index 000000000000..ec0dddb45274
--- /dev/null
+++ b/test/profile/Inputs/instrprof-dlopen-func3.c
@@ -0,0 +1 @@
+void func3(int K) {}
diff --git a/test/profile/Inputs/instrprof-dlopen-func3.c.gcov b/test/profile/Inputs/instrprof-dlopen-func3.c.gcov
new file mode 100644
index 000000000000..7101f74b938d
--- /dev/null
+++ b/test/profile/Inputs/instrprof-dlopen-func3.c.gcov
@@ -0,0 +1,6 @@
+// CHECK: -: 0:Source:{{.*}}Inputs/instrprof-dlopen-func2.c
+// CHECK-NEXT: -: 0:Graph:instrprof-dlopen-func2.gcno
+// CHECK-NEXT: -: 0:Data:instrprof-dlopen-func2.gcda
+// CHECK-NEXT: -: 0:Runs:1
+// CHECK-NEXT: -: 0:Programs:1
+// CHECK-NEXT: 1: 1:void func2(int K) {}
diff --git a/test/profile/Inputs/instrprof-gcov-__gcov_flush-terminate.c b/test/profile/Inputs/instrprof-gcov-__gcov_flush-terminate.c
new file mode 100644
index 000000000000..7b24d69c75fc
--- /dev/null
+++ b/test/profile/Inputs/instrprof-gcov-__gcov_flush-terminate.c
@@ -0,0 +1,13 @@
+int main(void) {
+ int i = 22;
+
+ __gcov_flush();
+
+ i = 42;
+
+ asm("int $3");
+
+ i = 84;
+
+ return 0;
+}
diff --git a/test/profile/Inputs/instrprof-gcov-__gcov_flush-terminate.c.gcov b/test/profile/Inputs/instrprof-gcov-__gcov_flush-terminate.c.gcov
new file mode 100644
index 000000000000..69e229a3127e
--- /dev/null
+++ b/test/profile/Inputs/instrprof-gcov-__gcov_flush-terminate.c.gcov
@@ -0,0 +1,18 @@
+// CHECK: -: 0:Source:{{.*}}Inputs/instrprof-gcov-__gcov_flush-terminate.c
+// CHECK-NEXT: -: 0:Graph:instrprof-gcov-__gcov_flush-terminate.gcno
+// CHECK-NEXT: -: 0:Data:instrprof-gcov-__gcov_flush-terminate.gcda
+// CHECK-NEXT: -: 0:Runs:1
+// CHECK-NEXT: -: 0:Programs:1
+// CHECK-NEXT: -: 1:int main(void) {
+// CHECK-NEXT: 1: 2: int i = 22;
+// CHECK-NEXT: -: 3:
+// CHECK-NEXT: 1: 4: __gcov_flush();
+// CHECK-NEXT: -: 5:
+// CHECK-NEXT: #####: 6: i = 42;
+// CHECK-NEXT: -: 7:
+// CHECK-NEXT: #####: 8: asm("int $3");
+// CHECK-NEXT: -: 9:
+// CHECK-NEXT: #####: 10: i = 84;
+// CHECK-NEXT: -: 11:
+// CHECK-NEXT: #####: 12: return 0;
+// CHECK-NEXT: -: 13:}
diff --git a/test/profile/Inputs/instrprof-gcov-exceptions.cpp b/test/profile/Inputs/instrprof-gcov-exceptions.cpp
new file mode 100644
index 000000000000..327966551d09
--- /dev/null
+++ b/test/profile/Inputs/instrprof-gcov-exceptions.cpp
@@ -0,0 +1,11 @@
+#include <string>
+
+void asd(std::string i) {
+}
+
+int main(void)
+{
+ asd("22");
+
+ return 0;
+}
diff --git a/test/profile/Inputs/instrprof-gcov-exceptions.cpp.gcov b/test/profile/Inputs/instrprof-gcov-exceptions.cpp.gcov
new file mode 100644
index 000000000000..7caf50806020
--- /dev/null
+++ b/test/profile/Inputs/instrprof-gcov-exceptions.cpp.gcov
@@ -0,0 +1,16 @@
+// CHECK: -: 0:Source:{{.*}}Inputs/instrprof-gcov-exceptions.cpp
+// CHECK-NEXT: -: 0:Graph:instrprof-gcov-exceptions.gcno
+// CHECK-NEXT: -: 0:Data:instrprof-gcov-exceptions.gcda
+// CHECK-NEXT: -: 0:Runs:1
+// CHECK-NEXT: -: 0:Programs:1
+// CHECK-NEXT: -: 1:#include <string>
+// CHECK-NEXT: -: 2:
+// CHECK-NEXT: -: 3:void asd(std::string i) {
+// CHECK-NEXT: 2: 4:}
+// CHECK-NEXT: -: 5:
+// CHECK-NEXT: -: 6:int main(void)
+// CHECK-NEXT: -: 7:{
+// CHECK-NEXT: 1: 8: asd("22");
+// CHECK-NEXT: -: 9:
+// CHECK-NEXT: 1: 10: return 0;
+// CHECK-NEXT: -: 11:}
diff --git a/test/profile/Inputs/instrprof-gcov-multiple-bbs-single-line.c b/test/profile/Inputs/instrprof-gcov-multiple-bbs-single-line.c
new file mode 100644
index 000000000000..a2e187b5cb61
--- /dev/null
+++ b/test/profile/Inputs/instrprof-gcov-multiple-bbs-single-line.c
@@ -0,0 +1,20 @@
+int main(void)
+{
+ int var;
+
+ int a = 1;
+ if (a) {
+ var++;
+ }
+
+ if (a) {}
+
+ int b = 0;
+ if (b) {
+ var++;
+ }
+
+ if (b) {}
+
+ return 0;
+}
diff --git a/test/profile/Inputs/instrprof-gcov-multiple-bbs-single-line.c.gcov b/test/profile/Inputs/instrprof-gcov-multiple-bbs-single-line.c.gcov
new file mode 100644
index 000000000000..92532af30674
--- /dev/null
+++ b/test/profile/Inputs/instrprof-gcov-multiple-bbs-single-line.c.gcov
@@ -0,0 +1,34 @@
+// CHECK: -: 0:Source:{{.*}}Inputs/instrprof-gcov-multiple-bbs-single-line.c
+// CHECK-NEXT: -: 0:Graph:instrprof-gcov-multiple-bbs-single-line.gcno
+// CHECK-NEXT: -: 0:Data:instrprof-gcov-multiple-bbs-single-line.gcda
+// CHECK-NEXT: -: 0:Runs:1
+// CHECK-NEXT: -: 0:Programs:1
+// CHECK-NEXT:function main called 1 returned 100% blocks executed 80%
+// CHECK-NEXT: -: 1:int main(void)
+// CHECK-NEXT: -: 2:{
+// CHECK-NEXT: -: 3: int var;
+// CHECK-NEXT: -: 4:
+// CHECK-NEXT: 1: 5: int a = 1;
+// CHECK-NEXT: 1: 6: if (a) {
+// CHECK-NEXT:branch 0 taken 1
+// CHECK-NEXT:branch 1 taken 0
+// CHECK-NEXT: 1: 7: var++;
+// CHECK-NEXT: 1: 8: }
+// CHECK-NEXT: -: 9:
+// CHECK-NEXT: 1: 10: if (a) {}
+// CHECK-NEXT:branch 0 taken 1
+// CHECK-NEXT:branch 1 taken 0
+// CHECK-NEXT: -: 11:
+// CHECK-NEXT: 1: 12: int b = 0;
+// CHECK-NEXT: 1: 13: if (b) {
+// CHECK-NEXT:branch 0 taken 0
+// CHECK-NEXT:branch 1 taken 1
+// CHECK-NEXT: #####: 14: var++;
+// CHECK-NEXT: #####: 15: }
+// CHECK-NEXT: -: 16:
+// CHECK-NEXT: 1: 17: if (b) {}
+// CHECK-NEXT:branch 0 taken 0
+// CHECK-NEXT:branch 1 taken 1
+// CHECK-NEXT: -: 18:
+// CHECK-NEXT: 1: 19: return 0;
+// CHECK-NEXT: -: 20:}
diff --git a/test/profile/Inputs/instrprof-shared-lib.c.gcov b/test/profile/Inputs/instrprof-shared-lib.c.gcov
new file mode 100644
index 000000000000..fbc43d5f7d50
--- /dev/null
+++ b/test/profile/Inputs/instrprof-shared-lib.c.gcov
@@ -0,0 +1,14 @@
+// CHECK: -: 0:Source:{{.*}}Inputs/instrprof-shared-lib.c
+// CHECK-NEXT: -: 0:Graph:instrprof-shared-lib.gcno
+// CHECK-NEXT: -: 0:Data:instrprof-shared-lib.gcda
+// CHECK-NEXT: -: 0:Runs:1
+// CHECK-NEXT: -: 0:Programs:1
+// CHECK-NEXT: -: 1:int g1 = 0;
+// CHECK-NEXT: -: 2:int g2 = 1;
+// CHECK-NEXT: -: 3:
+// CHECK-NEXT: -: 4:void foo(int n) {
+// CHECK-NEXT: 1: 5: if (n % 5 == 0)
+// CHECK-NEXT: #####: 6: g1++;
+// CHECK-NEXT: -: 7: else
+// CHECK-NEXT: 1: 8: g2++;
+// CHECK-NEXT: 1: 9:}
diff --git a/test/profile/Inputs/instrprof-shared-lib_called-twice.c.gcov b/test/profile/Inputs/instrprof-shared-lib_called-twice.c.gcov
new file mode 100644
index 000000000000..779c885d862d
--- /dev/null
+++ b/test/profile/Inputs/instrprof-shared-lib_called-twice.c.gcov
@@ -0,0 +1,14 @@
+// CHECK: -: 0:Source:{{.*}}Inputs/instrprof-shared-lib.c
+// CHECK-NEXT: -: 0:Graph:instrprof-shared-lib.gcno
+// CHECK-NEXT: -: 0:Data:instrprof-shared-lib.gcda
+// CHECK-NEXT: -: 0:Runs:1
+// CHECK-NEXT: -: 0:Programs:1
+// CHECK-NEXT: -: 1:int g1 = 0;
+// CHECK-NEXT: -: 2:int g2 = 1;
+// CHECK-NEXT: -: 3:
+// CHECK-NEXT: -: 4:void foo(int n) {
+// CHECK-NEXT: 2: 5: if (n % 5 == 0)
+// CHECK-NEXT: #####: 6: g1++;
+// CHECK-NEXT: -: 7: else
+// CHECK-NEXT: 2: 8: g2++;
+// CHECK-NEXT: 2: 9:}
diff --git a/test/profile/Inputs/instrprof-shared-lib_in-loop.c.gcov b/test/profile/Inputs/instrprof-shared-lib_in-loop.c.gcov
new file mode 100644
index 000000000000..76503d91426e
--- /dev/null
+++ b/test/profile/Inputs/instrprof-shared-lib_in-loop.c.gcov
@@ -0,0 +1,14 @@
+// CHECK: -: 0:Source:{{.*}}Inputs/instrprof-shared-lib.c
+// CHECK-NEXT: -: 0:Graph:instrprof-shared-lib.gcno
+// CHECK-NEXT: -: 0:Data:instrprof-shared-lib.gcda
+// CHECK-NEXT: -: 0:Runs:1
+// CHECK-NEXT: -: 0:Programs:1
+// CHECK-NEXT: -: 1:int g1 = 0;
+// CHECK-NEXT: -: 2:int g2 = 1;
+// CHECK-NEXT: -: 3:
+// CHECK-NEXT: -: 4:void foo(int n) {
+// CHECK-NEXT: 1000000: 5: if (n % 5 == 0)
+// CHECK-NEXT: 360000: 6: g1++;
+// CHECK-NEXT: -: 7: else
+// CHECK-NEXT: 640000: 8: g2++;
+// CHECK-NEXT: 1000000: 9:}
diff --git a/test/profile/Inputs/instrprof-shared-main-gcov-flush.c b/test/profile/Inputs/instrprof-shared-main-gcov-flush.c
new file mode 100644
index 000000000000..9f41b7e6362a
--- /dev/null
+++ b/test/profile/Inputs/instrprof-shared-main-gcov-flush.c
@@ -0,0 +1,36 @@
+extern void foo(int n);
+extern void __gcov_flush(void);
+
+int bar1 = 0;
+int bar2 = 1;
+
+void bar(int n) {
+ if (n % 5 == 0)
+ bar1++;
+ else
+ bar2++;
+}
+
+int main(int argc, char *argv[]) {
+#ifdef SHARED_CALL_BEFORE_GCOV_FLUSH
+ foo(1);
+#endif
+
+ bar(5);
+
+ __gcov_flush();
+
+ bar(5);
+
+#ifdef SHARED_CALL_AFTER_GCOV_FLUSH
+ foo(1);
+#endif
+
+#ifdef EXIT_ABRUPTLY
+ _exit(0);
+#endif
+
+ bar(5);
+
+ return 0;
+}
diff --git a/test/profile/Inputs/instrprof-shared-main-gcov-flush_no-writeout.c.gcov b/test/profile/Inputs/instrprof-shared-main-gcov-flush_no-writeout.c.gcov
new file mode 100644
index 000000000000..b2dfe2acde67
--- /dev/null
+++ b/test/profile/Inputs/instrprof-shared-main-gcov-flush_no-writeout.c.gcov
@@ -0,0 +1,41 @@
+// CHECK: -: 0:Source:{{.*}}Inputs/instrprof-shared-main-gcov-flush.c
+// CHECK-NEXT: -: 0:Graph:instrprof-shared-main-gcov-flush.gcno
+// CHECK-NEXT: -: 0:Data:instrprof-shared-main-gcov-flush.gcda
+// CHECK-NEXT: -: 0:Runs:1
+// CHECK-NEXT: -: 0:Programs:1
+// CHECK-NEXT: -: 1:extern void foo(int n);
+// CHECK-NEXT: -: 2:extern void __gcov_flush(void);
+// CHECK-NEXT: -: 3:
+// CHECK-NEXT: -: 4:int bar1 = 0;
+// CHECK-NEXT: -: 5:int bar2 = 1;
+// CHECK-NEXT: -: 6:
+// CHECK-NEXT: -: 7:void bar(int n) {
+// CHECK-NEXT: 1: 8: if (n % 5 == 0)
+// CHECK-NEXT: 1: 9: bar1++;
+// CHECK-NEXT: -: 10: else
+// CHECK-NEXT: #####: 11: bar2++;
+// CHECK-NEXT: 1: 12:}
+// CHECK-NEXT: -: 13:
+// CHECK-NEXT: -: 14:int main(int argc, char *argv[]) {
+// CHECK-NEXT: -: 15:#ifdef SHARED_CALL_BEFORE_GCOV_FLUSH
+// CHECK-NEXT: 1: 16: foo(1);
+// CHECK-NEXT: -: 17:#endif
+// CHECK-NEXT: -: 18:
+// CHECK-NEXT: 1: 19: bar(5);
+// CHECK-NEXT: -: 20:
+// CHECK-NEXT: 1: 21: __gcov_flush();
+// CHECK-NEXT: -: 22:
+// CHECK-NEXT: 1: 23: bar(5);
+// CHECK-NEXT: -: 24:
+// CHECK-NEXT: -: 25:#ifdef SHARED_CALL_AFTER_GCOV_FLUSH
+// CHECK-NEXT: 1: 26: foo(1);
+// CHECK-NEXT: -: 27:#endif
+// CHECK-NEXT: -: 28:
+// CHECK-NEXT: -: 29:#ifdef EXIT_ABRUPTLY
+// CHECK-NEXT: 1: 30: _exit(0);
+// CHECK-NEXT: -: 31:#endif
+// CHECK-NEXT: -: 32:
+// CHECK-NEXT: -: 33: bar(5);
+// CHECK-NEXT: -: 34:
+// CHECK-NEXT: -: 35: return 0;
+// CHECK-NEXT: #####: 36:}
diff --git a/test/profile/Inputs/instrprof-shared-main-gcov-flush_shared-call-after.c.gcov b/test/profile/Inputs/instrprof-shared-main-gcov-flush_shared-call-after.c.gcov
new file mode 100644
index 000000000000..f70e34e52894
--- /dev/null
+++ b/test/profile/Inputs/instrprof-shared-main-gcov-flush_shared-call-after.c.gcov
@@ -0,0 +1,41 @@
+// CHECK: -: 0:Source:{{.*}}Inputs/instrprof-shared-main-gcov-flush.c
+// CHECK-NEXT: -: 0:Graph:instrprof-shared-main-gcov-flush.gcno
+// CHECK-NEXT: -: 0:Data:instrprof-shared-main-gcov-flush.gcda
+// CHECK-NEXT: -: 0:Runs:1
+// CHECK-NEXT: -: 0:Programs:1
+// CHECK-NEXT: -: 1:extern void foo(int n);
+// CHECK-NEXT: -: 2:extern void __gcov_flush(void);
+// CHECK-NEXT: -: 3:
+// CHECK-NEXT: -: 4:int bar1 = 0;
+// CHECK-NEXT: -: 5:int bar2 = 1;
+// CHECK-NEXT: -: 6:
+// CHECK-NEXT: -: 7:void bar(int n) {
+// CHECK-NEXT: 3: 8: if (n % 5 == 0)
+// CHECK-NEXT: 3: 9: bar1++;
+// CHECK-NEXT: -: 10: else
+// CHECK-NEXT: #####: 11: bar2++;
+// CHECK-NEXT: 3: 12:}
+// CHECK-NEXT: -: 13:
+// CHECK-NEXT: -: 14:int main(int argc, char *argv[]) {
+// CHECK-NEXT: -: 15:#ifdef SHARED_CALL_BEFORE_GCOV_FLUSH
+// CHECK-NEXT: -: 16: foo(1);
+// CHECK-NEXT: -: 17:#endif
+// CHECK-NEXT: -: 18:
+// CHECK-NEXT: 1: 19: bar(5);
+// CHECK-NEXT: -: 20:
+// CHECK-NEXT: 1: 21: __gcov_flush();
+// CHECK-NEXT: -: 22:
+// CHECK-NEXT: 1: 23: bar(5);
+// CHECK-NEXT: -: 24:
+// CHECK-NEXT: -: 25:#ifdef SHARED_CALL_AFTER_GCOV_FLUSH
+// CHECK-NEXT: 1: 26: foo(1);
+// CHECK-NEXT: -: 27:#endif
+// CHECK-NEXT: -: 28:
+// CHECK-NEXT: -: 29:#ifdef EXIT_ABRUPTLY
+// CHECK-NEXT: -: 30: _exit(0);
+// CHECK-NEXT: -: 31:#endif
+// CHECK-NEXT: -: 32:
+// CHECK-NEXT: 1: 33: bar(5);
+// CHECK-NEXT: -: 34:
+// CHECK-NEXT: 1: 35: return 0;
+// CHECK-NEXT: -: 36:}
diff --git a/test/profile/Inputs/instrprof-shared-main-gcov-flush_shared-call-before-after.c.gcov b/test/profile/Inputs/instrprof-shared-main-gcov-flush_shared-call-before-after.c.gcov
new file mode 100644
index 000000000000..b9ecff698722
--- /dev/null
+++ b/test/profile/Inputs/instrprof-shared-main-gcov-flush_shared-call-before-after.c.gcov
@@ -0,0 +1,41 @@
+// CHECK: -: 0:Source:{{.*}}Inputs/instrprof-shared-main-gcov-flush.c
+// CHECK-NEXT: -: 0:Graph:instrprof-shared-main-gcov-flush.gcno
+// CHECK-NEXT: -: 0:Data:instrprof-shared-main-gcov-flush.gcda
+// CHECK-NEXT: -: 0:Runs:1
+// CHECK-NEXT: -: 0:Programs:1
+// CHECK-NEXT: -: 1:extern void foo(int n);
+// CHECK-NEXT: -: 2:extern void __gcov_flush(void);
+// CHECK-NEXT: -: 3:
+// CHECK-NEXT: -: 4:int bar1 = 0;
+// CHECK-NEXT: -: 5:int bar2 = 1;
+// CHECK-NEXT: -: 6:
+// CHECK-NEXT: -: 7:void bar(int n) {
+// CHECK-NEXT: 3: 8: if (n % 5 == 0)
+// CHECK-NEXT: 3: 9: bar1++;
+// CHECK-NEXT: -: 10: else
+// CHECK-NEXT: #####: 11: bar2++;
+// CHECK-NEXT: 3: 12:}
+// CHECK-NEXT: -: 13:
+// CHECK-NEXT: -: 14:int main(int argc, char *argv[]) {
+// CHECK-NEXT: -: 15:#ifdef SHARED_CALL_BEFORE_GCOV_FLUSH
+// CHECK-NEXT: 1: 16: foo(1);
+// CHECK-NEXT: -: 17:#endif
+// CHECK-NEXT: -: 18:
+// CHECK-NEXT: 1: 19: bar(5);
+// CHECK-NEXT: -: 20:
+// CHECK-NEXT: 1: 21: __gcov_flush();
+// CHECK-NEXT: -: 22:
+// CHECK-NEXT: 1: 23: bar(5);
+// CHECK-NEXT: -: 24:
+// CHECK-NEXT: -: 25:#ifdef SHARED_CALL_AFTER_GCOV_FLUSH
+// CHECK-NEXT: 1: 26: foo(1);
+// CHECK-NEXT: -: 27:#endif
+// CHECK-NEXT: -: 28:
+// CHECK-NEXT: -: 29:#ifdef EXIT_ABRUPTLY
+// CHECK-NEXT: -: 30: _exit(0);
+// CHECK-NEXT: -: 31:#endif
+// CHECK-NEXT: -: 32:
+// CHECK-NEXT: 1: 33: bar(5);
+// CHECK-NEXT: -: 34:
+// CHECK-NEXT: 1: 35: return 0;
+// CHECK-NEXT: -: 36:}
diff --git a/test/profile/Inputs/instrprof-shared-main-gcov-flush_shared-call-before.c.gcov b/test/profile/Inputs/instrprof-shared-main-gcov-flush_shared-call-before.c.gcov
new file mode 100644
index 000000000000..7c9e0afa11b2
--- /dev/null
+++ b/test/profile/Inputs/instrprof-shared-main-gcov-flush_shared-call-before.c.gcov
@@ -0,0 +1,41 @@
+// CHECK: -: 0:Source:{{.*}}Inputs/instrprof-shared-main-gcov-flush.c
+// CHECK-NEXT: -: 0:Graph:instrprof-shared-main-gcov-flush.gcno
+// CHECK-NEXT: -: 0:Data:instrprof-shared-main-gcov-flush.gcda
+// CHECK-NEXT: -: 0:Runs:1
+// CHECK-NEXT: -: 0:Programs:1
+// CHECK-NEXT: -: 1:extern void foo(int n);
+// CHECK-NEXT: -: 2:extern void __gcov_flush(void);
+// CHECK-NEXT: -: 3:
+// CHECK-NEXT: -: 4:int bar1 = 0;
+// CHECK-NEXT: -: 5:int bar2 = 1;
+// CHECK-NEXT: -: 6:
+// CHECK-NEXT: -: 7:void bar(int n) {
+// CHECK-NEXT: 3: 8: if (n % 5 == 0)
+// CHECK-NEXT: 3: 9: bar1++;
+// CHECK-NEXT: -: 10: else
+// CHECK-NEXT: #####: 11: bar2++;
+// CHECK-NEXT: 3: 12:}
+// CHECK-NEXT: -: 13:
+// CHECK-NEXT: -: 14:int main(int argc, char *argv[]) {
+// CHECK-NEXT: -: 15:#ifdef SHARED_CALL_BEFORE_GCOV_FLUSH
+// CHECK-NEXT: 1: 16: foo(1);
+// CHECK-NEXT: -: 17:#endif
+// CHECK-NEXT: -: 18:
+// CHECK-NEXT: 1: 19: bar(5);
+// CHECK-NEXT: -: 20:
+// CHECK-NEXT: 1: 21: __gcov_flush();
+// CHECK-NEXT: -: 22:
+// CHECK-NEXT: 1: 23: bar(5);
+// CHECK-NEXT: -: 24:
+// CHECK-NEXT: -: 25:#ifdef SHARED_CALL_AFTER_GCOV_FLUSH
+// CHECK-NEXT: -: 26: foo(1);
+// CHECK-NEXT: -: 27:#endif
+// CHECK-NEXT: -: 28:
+// CHECK-NEXT: -: 29:#ifdef EXIT_ABRUPTLY
+// CHECK-NEXT: -: 30: _exit(0);
+// CHECK-NEXT: -: 31:#endif
+// CHECK-NEXT: -: 32:
+// CHECK-NEXT: 1: 33: bar(5);
+// CHECK-NEXT: -: 34:
+// CHECK-NEXT: 1: 35: return 0;
+// CHECK-NEXT: -: 36:}
diff --git a/test/profile/Inputs/instrprof-shared-main.c.gcov b/test/profile/Inputs/instrprof-shared-main.c.gcov
new file mode 100644
index 000000000000..70be367507ff
--- /dev/null
+++ b/test/profile/Inputs/instrprof-shared-main.c.gcov
@@ -0,0 +1,18 @@
+// CHECK: -: 0:Source:{{.*}}Inputs/instrprof-shared-main.c
+// CHECK-NEXT: -: 0:Graph:instrprof-shared-main.gcno
+// CHECK-NEXT: -: 0:Data:instrprof-shared-main.gcda
+// CHECK-NEXT: -: 0:Runs:1
+// CHECK-NEXT: -: 0:Programs:1
+// CHECK-NEXT: -: 1:extern int g1, g2;
+// CHECK-NEXT: -: 2:extern void foo(int n);
+// CHECK-NEXT: -: 3:
+// CHECK-NEXT: -: 4:int main() {
+// CHECK-NEXT: -: 5: int i, j;
+// CHECK-NEXT: 2002: 6: for (i = 0; i < 1000; i++)
+// CHECK-NEXT: 2002000: 7: for (j = 0; j < 1000; j++)
+// CHECK-NEXT: 1001000: 8: foo(i * j);
+// CHECK-NEXT: -: 9:
+// CHECK-NEXT: 1: 10: if (g2 - g1 == 280001)
+// CHECK-NEXT: 1: 11: return 0;
+// CHECK-NEXT: #####: 12: return 1;
+// CHECK-NEXT: 1: 13:}
diff --git a/test/profile/Linux/counter_promo_nest.c b/test/profile/Linux/counter_promo_nest.c
index 0792f0c76abb..ebd52dda7f48 100644
--- a/test/profile/Linux/counter_promo_nest.c
+++ b/test/profile/Linux/counter_promo_nest.c
@@ -25,6 +25,9 @@ int main()
// PROMO: load{{.*}}@__profc_main{{.*}}
// PROMO-NEXT: add
// PROMO-NEXT: store{{.*}}@__profc_main{{.*}}
+// PROMO: load{{.*}}@__profc_main{{.*}}
+// PROMO-NEXT: add
+// PROMO-NEXT: store{{.*}}@__profc_main{{.*}}
// PROMO-NEXT: load{{.*}}@__profc_main{{.*}}
// PROMO-NEXT: add
// PROMO-NEXT: store{{.*}}@__profc_main{{.*}}
diff --git a/test/profile/Linux/instrprof-value-merge.c b/test/profile/Linux/instrprof-value-merge.c
new file mode 100644
index 000000000000..902430a4a968
--- /dev/null
+++ b/test/profile/Linux/instrprof-value-merge.c
@@ -0,0 +1,79 @@
+// RUN: %clang_pgogen -o %t -O3 %s
+// RUN: rm -rf %t.profdir
+// RUN: env LLVM_PROFILE_FILE=%t.profdir/default_%m.profraw %run %t
+// RUN: env LLVM_PROFILE_FILE=%t.profdir/default_%m.profraw %run %t
+// RUN: env LLVM_PROFILE_FILE=%t.profdir/default_%m.profraw %run %t
+// RUN: env LLVM_PROFILE_FILE=%t.profdir/default_%m.profraw %run %t 1
+// RUN: env LLVM_PROFILE_FILE=%t.profdir/default_%m.profraw %run %t 1
+// RUN: llvm-profdata show -counts -function=main -ic-targets -memop-sizes %t.profdir/default_*.profraw | FileCheck %s
+
+#include <string.h>
+
+void (*f0)();
+void (*f1)();
+void (*f2)();
+
+char dst[200];
+char src[200];
+volatile int n;
+
+__attribute__((noinline)) void foo() {}
+
+__attribute__((noinline)) void bar() {
+ f0 = foo;
+ f1 = foo;
+ f2 = foo;
+ n = 4;
+}
+int main(int argc, char *argv[]) {
+ int i;
+ bar();
+ if (argc == 1) {
+ f0();
+ for (i = 0; i < 9; i++)
+ f1();
+ for (i = 0; i < 99; i++)
+ f2();
+ } else {
+ memcpy((void *)dst, (void *)src, n);
+ for (i = 0; i < 6; i++)
+ memcpy((void *)(dst + 2), (void *)src, n + 1);
+ for (i = 0; i < 66; i++)
+ memcpy((void *)(dst + 9), (void *)src, n + 2);
+ }
+}
+
+// CHECK: Counters:
+// CHECK: main:
+// CHECK: Hash: 0x00030012a7ab6e87
+// CHECK: Counters: 6
+// CHECK: Indirect Call Site Count: 3
+// CHECK: Number of Memory Intrinsics Calls: 3
+// CHECK: Block counts: [27, 297, 12, 132, 3, 2]
+// CHECK: Indirect Target Results:
+// CHECK: [ 0, foo, 3 ]
+// CHECK: [ 1, foo, 27 ]
+// CHECK: [ 2, foo, 297 ]
+// CHECK: Memory Intrinsic Size Results:
+// CHECK: [ 0, 4, 2 ]
+// CHECK: [ 1, 5, 12 ]
+// CHECK: [ 2, 6, 132 ]
+// CHECK: Instrumentation level: IR
+// CHECK: Functions shown: 1
+// CHECK: Total functions: 3
+// CHECK: Maximum function count: 327
+// CHECK: Maximum internal block count: 297
+// CHECK: Statistics for indirect call sites profile:
+// CHECK: Total number of sites: 3
+// CHECK: Total number of sites with values: 3
+// CHECK: Total number of profiled values: 3
+// CHECK: Value sites histogram:
+// CHECK: NumTargets, SiteCount
+// CHECK: 1, 3
+// CHECK: Statistics for memory intrinsic calls sizes profile:
+// CHECK: Total number of sites: 3
+// CHECK: Total number of sites with values: 3
+// CHECK: Total number of profiled values: 3
+// CHECK: Value sites histogram:
+// CHECK: NumTargets, SiteCount
+// CHECK: 1, 3
diff --git a/test/profile/instrprof-darwin-dead-strip.c b/test/profile/instrprof-darwin-dead-strip.c
index 03049335efda..6a2bffc213a3 100644
--- a/test/profile/instrprof-darwin-dead-strip.c
+++ b/test/profile/instrprof-darwin-dead-strip.c
@@ -1,7 +1,7 @@
// REQUIRES: osx-ld64-live_support
// REQUIRES: lto
-// RUN: %clang_profgen=%t.profraw -fcoverage-mapping -mllvm -enable-name-compression=false -Wl,-dead_strip -o %t %s
+// RUN: %clang_profgen=%t.profraw -fcoverage-mapping -mllvm -enable-name-compression=false -DCODE=1 -Wl,-dead_strip -o %t %s
// RUN: %run %t
// RUN: llvm-profdata merge -o %t.profdata %t.profraw
// RUN: llvm-profdata show --all-functions %t.profdata | FileCheck %s -check-prefix=PROF
@@ -10,7 +10,7 @@
// RUN: otool -s __DATA __llvm_prf_names %t | FileCheck %s -check-prefix=PRF_NAMES
// RUN: otool -s __DATA __llvm_prf_cnts %t | FileCheck %s -check-prefix=PRF_CNTS
-// RUN: %clang_lto_profgen=%t.lto.profraw -fcoverage-mapping -mllvm -enable-name-compression=false -Wl,-dead_strip -flto -o %t.lto %s
+// RUN: %clang_lto_profgen=%t.lto.profraw -fcoverage-mapping -mllvm -enable-name-compression=false -DCODE=1 -Wl,-dead_strip -flto -o %t.lto %s
// RUN: %run %t.lto
// RUN: llvm-profdata merge -o %t.lto.profdata %t.lto.profraw
// RUN: llvm-profdata show --all-functions %t.lto.profdata | FileCheck %s -check-prefix=PROF
@@ -22,12 +22,24 @@
// Note: We expect foo() and some of the profiling data associated with it to
// be dead-stripped.
+// Note: When there is no code in a program, we expect to see the exact same
+// set of external functions provided by the profile runtime.
+
+// RUN: %clang_profgen -fcoverage-mapping -Wl,-dead_strip -dynamiclib -o %t.nocode.dylib %s
+// RUN: nm -jgU %t.nocode.dylib > %t.nocode.syms
+// RUN: nm -jgU %t | grep -vE "main|foo|mh_execute_header" > %t.code.syms
+// RUN: diff %t.nocode.syms %t.code.syms
+
+#ifdef CODE
+
// COV: [[@LINE+1]]{{ *}}|{{ *}}0|void foo()
void foo() {}
// COV: [[@LINE+1]]{{ *}}|{{ *}}1|int main
int main() { return 0; }
+#endif // CODE
+
// NM-NOT: foo
// PROF: Counters:
diff --git a/test/profile/instrprof-darwin-exports.c b/test/profile/instrprof-darwin-exports.c
new file mode 100644
index 000000000000..6667cabdb2df
--- /dev/null
+++ b/test/profile/instrprof-darwin-exports.c
@@ -0,0 +1,11 @@
+// REQUIRES: osx-ld64-live_support
+
+// Compiling with PGO/code coverage on Darwin should raise no warnings or errors
+// when using an exports list.
+
+// RUN: echo "_main" > %t.exports
+// RUN: %clang_pgogen -Werror -Wl,-exported_symbols_list,%t.exports -o %t %s 2>&1 | tee %t.log
+// RUN: %clang_profgen -Werror -fcoverage-mapping -Wl,-exported_symbols_list,%t.exports -o %t %s 2>&1 | tee -a %t.log
+// RUN: cat %t.log | count 0
+
+int main() {}
diff --git a/test/profile/instrprof-dlopen-dlclose-gcov.test b/test/profile/instrprof-dlopen-dlclose-gcov.test
new file mode 100644
index 000000000000..0444fca2692c
--- /dev/null
+++ b/test/profile/instrprof-dlopen-dlclose-gcov.test
@@ -0,0 +1,30 @@
+RUN: mkdir -p %t.d
+RUN: cd %t.d
+
+RUN: %clang --coverage -o func.shared -fPIC -shared %S/Inputs/instrprof-dlopen-func.c
+RUN: %clang --coverage -o func2.shared -fPIC -shared %S/Inputs/instrprof-dlopen-func2.c
+RUN: %clang --coverage -o func3.shared -fPIC -shared %S/Inputs/instrprof-dlopen-func3.c
+RUN: %clang --coverage -o %t -fPIC -rpath %t.d %S/Inputs/instrprof-dlopen-dlclose-main.c
+
+# Test with two dlopened libraries.
+RUN: %run %t
+RUN: llvm-cov gcov instrprof-dlopen-dlclose-main.gcda
+RUN: FileCheck --match-full-lines --strict-whitespace --input-file instrprof-dlopen-dlclose-main.c.gcov %S/Inputs/instrprof-dlopen-dlclose-main.c.gcov
+RUN: llvm-cov gcov instrprof-dlopen-func.gcda
+RUN: FileCheck --match-full-lines --strict-whitespace --input-file instrprof-dlopen-func.c.gcov %S/Inputs/instrprof-dlopen-func.c.gcov
+RUN: llvm-cov gcov instrprof-dlopen-func2.gcda
+RUN: FileCheck --match-full-lines --strict-whitespace --input-file instrprof-dlopen-func2.c.gcov %S/Inputs/instrprof-dlopen-func2.c.gcov
+RUN: rm instrprof-dlopen-dlclose-main.gcda instrprof-dlopen-func.gcda instrprof-dlopen-func2.gcda
+
+# Test with three dlopened libraries.
+RUN: %clang -DUSE_LIB3 --coverage -o %t -fPIC -rpath %t.d %S/Inputs/instrprof-dlopen-dlclose-main.c
+RUN: %run %t
+RUN: llvm-cov gcov instrprof-dlopen-dlclose-main.gcda
+RUN: FileCheck --match-full-lines --strict-whitespace --input-file instrprof-dlopen-dlclose-main.c.gcov %S/Inputs/instrprof-dlopen-dlclose-main_three-libs.c.gcov
+RUN: llvm-cov gcov instrprof-dlopen-func.gcda
+RUN: FileCheck --match-full-lines --strict-whitespace --input-file instrprof-dlopen-func.c.gcov %S/Inputs/instrprof-dlopen-func.c.gcov
+RUN: llvm-cov gcov instrprof-dlopen-func2.gcda
+RUN: FileCheck --match-full-lines --strict-whitespace --input-file instrprof-dlopen-func2.c.gcov %S/Inputs/instrprof-dlopen-func2.c.gcov
+RUN: llvm-cov gcov instrprof-dlopen-func3.gcda
+RUN: FileCheck --match-full-lines --strict-whitespace --input-file instrprof-dlopen-func2.c.gcov %S/Inputs/instrprof-dlopen-func3.c.gcov
+RUN: rm instrprof-dlopen-dlclose-main.gcda instrprof-dlopen-func.gcda instrprof-dlopen-func2.gcda instrprof-dlopen-func3.gcda
diff --git a/test/profile/instrprof-gcov-__gcov_flush-terminate.test b/test/profile/instrprof-gcov-__gcov_flush-terminate.test
new file mode 100644
index 000000000000..aa51461a3bd0
--- /dev/null
+++ b/test/profile/instrprof-gcov-__gcov_flush-terminate.test
@@ -0,0 +1,12 @@
+XFAIL: *
+
+RUN: mkdir -p %t.d
+RUN: cd %t.d
+
+RUN: %clang --coverage -o %t %S/Inputs/instrprof-gcov-__gcov_flush-terminate.c
+RUN: test -f instrprof-gcov-__gcov_flush-terminate.gcno
+
+RUN: rm -f instrprof-gcov-__gcov_flush-terminate.gcda
+RUN: %expect_crash %run %t
+RUN: llvm-cov gcov instrprof-gcov-__gcov_flush-terminate.gcda
+RUN: FileCheck --match-full-lines --strict-whitespace --input-file instrprof-gcov-__gcov_flush-terminate.c.gcov %S/Inputs/instrprof-gcov-__gcov_flush-terminate.c.gcov
diff --git a/test/profile/instrprof-gcov-exceptions.test b/test/profile/instrprof-gcov-exceptions.test
new file mode 100644
index 000000000000..20ca47a9528b
--- /dev/null
+++ b/test/profile/instrprof-gcov-exceptions.test
@@ -0,0 +1,21 @@
+RUN: mkdir -p %t.d
+RUN: cd %t.d
+
+# Test with exceptions disabled.
+RUN: %clangxx --coverage -o %t %S/Inputs/instrprof-gcov-exceptions.cpp -fno-exceptions
+RUN: test -f instrprof-gcov-exceptions.gcno
+
+RUN: rm -f instrprof-gcov-exceptions.gcda
+RUN: %run %t
+RUN: llvm-cov gcov instrprof-gcov-exceptions.gcda
+RUN: FileCheck --match-full-lines --strict-whitespace --input-file instrprof-gcov-exceptions.cpp.gcov %S/Inputs/instrprof-gcov-exceptions.cpp.gcov
+
+# Test with exceptions enabled, the result in terms of line counts should be the same.
+RUN: %clangxx --coverage -o %t %S/Inputs/instrprof-gcov-exceptions.cpp
+RUN: test -f instrprof-gcov-exceptions.gcno
+
+RUN: rm -f instrprof-gcov-exceptions.gcda
+RUN: %run %t
+RUN: llvm-cov gcov instrprof-gcov-exceptions.gcda
+# The result should be the same, not using XFAIL as only this part of the test is failing.
+RUN: not FileCheck --match-full-lines --strict-whitespace --input-file instrprof-gcov-exceptions.cpp.gcov %S/Inputs/instrprof-gcov-exceptions.cpp.gcov
diff --git a/test/profile/instrprof-gcov-multiple-bbs-single-line.test b/test/profile/instrprof-gcov-multiple-bbs-single-line.test
new file mode 100644
index 000000000000..8839455189ee
--- /dev/null
+++ b/test/profile/instrprof-gcov-multiple-bbs-single-line.test
@@ -0,0 +1,13 @@
+XFAIL: *
+
+RUN: mkdir -p %t.d
+RUN: cd %t.d
+
+RUN: %clang --coverage -o %t %S/Inputs/instrprof-gcov-multiple-bbs-single-line.c
+RUN: test -f instrprof-gcov-multiple-bbs-single-line.gcno
+
+RUN: rm -f instrprof-gcov-multiple-bbs-single-line.gcda
+RUN: %run %t
+RUN: llvm-cov gcov -b -c instrprof-gcov-multiple-bbs-single-line.gcda
+RUN: FileCheck --match-full-lines --strict-whitespace --input-file instrprof-gcov-multiple-bbs-single-line.c.gcov %S/Inputs/instrprof-gcov-multiple-bbs-single-line.c.gcov
+RUN: rm instrprof-gcov-multiple-bbs-single-line.gcda
diff --git a/test/profile/instrprof-gcov-two-objects.test b/test/profile/instrprof-gcov-two-objects.test
new file mode 100644
index 000000000000..a53d51dce8ed
--- /dev/null
+++ b/test/profile/instrprof-gcov-two-objects.test
@@ -0,0 +1,18 @@
+RUN: mkdir -p %t.d
+RUN: cd %t.d
+
+RUN: %clang --coverage -o instrprof-shared-lib.o -c %S/Inputs/instrprof-shared-lib.c
+RUN: test -f instrprof-shared-lib.gcno
+
+RUN: %clang --coverage -o instrprof-shared-main.o -c %S/Inputs/instrprof-shared-main.c
+RUN: test -f instrprof-shared-main.gcno
+
+RUN: %clang --coverage -o %t instrprof-shared-main.o instrprof-shared-lib.o
+RUN: test -f %t
+
+RUN: %run %t
+RUN: llvm-cov gcov instrprof-shared-main.gcda
+RUN: FileCheck --match-full-lines --strict-whitespace --input-file instrprof-shared-main.c.gcov %S/Inputs/instrprof-shared-main.c.gcov
+RUN: llvm-cov gcov instrprof-shared-lib.gcda
+RUN: FileCheck --match-full-lines --strict-whitespace --input-file instrprof-shared-lib.c.gcov %S/Inputs/instrprof-shared-lib_in-loop.c.gcov
+RUN: rm instrprof-shared-main.gcda instrprof-shared-lib.gcda
diff --git a/test/profile/instrprof-get-filename.c b/test/profile/instrprof-get-filename.c
new file mode 100644
index 000000000000..031b75f12f3c
--- /dev/null
+++ b/test/profile/instrprof-get-filename.c
@@ -0,0 +1,39 @@
+// Test __llvm_profile_get_filename.
+// RUN: %clang_pgogen -O2 -o %t %s
+// RUN: %run %t
+
+#include <stdio.h>
+#include <string.h>
+
+const char *__llvm_profile_get_filename();
+void __llvm_profile_set_filename(const char *);
+
+int main(int argc, const char *argv[]) {
+ int i;
+ const char *filename;
+ const char *new_filename = "/path/to/test.profraw";
+
+ filename = __llvm_profile_get_filename();
+ if (strncmp(filename, "default_", 8)) {
+ fprintf(stderr,
+ "Error: got filename %s, expected it to start with 'default_'\n",
+ filename);
+ return 1;
+ }
+ if (strcmp(filename + strlen(filename) - strlen(".profraw"), ".profraw")) {
+ fprintf(stderr,
+ "Error: got filename %s, expected it to end with '.profraw'\n",
+ filename);
+ return 1;
+ }
+
+ __llvm_profile_set_filename(new_filename);
+ filename = __llvm_profile_get_filename();
+ if (strcmp(filename, new_filename)) {
+ fprintf(stderr, "Error: got filename %s, expected '%s'\n", filename,
+ new_filename);
+ return 1;
+ }
+
+ return 0;
+}
diff --git a/test/profile/instrprof-path.c b/test/profile/instrprof-path.c
index 28ee8ad0a484..90cb1df198f0 100644
--- a/test/profile/instrprof-path.c
+++ b/test/profile/instrprof-path.c
@@ -12,7 +12,7 @@
#include <string.h>
const char *__llvm_profile_get_path_prefix();
-void __llvm_profile_set_filanem(const char*);
+void __llvm_profile_set_filename(const char*);
int main(int argc, const char *argv[]) {
int i;
diff --git a/test/profile/instrprof-reset-counters.c b/test/profile/instrprof-reset-counters.c
index e8892366bcfe..f15bc0d8e3a1 100644
--- a/test/profile/instrprof-reset-counters.c
+++ b/test/profile/instrprof-reset-counters.c
@@ -12,7 +12,7 @@ int main(void) {
return 0;
}
void foo(int N) {
- // CHECK-LABEL: define void @foo(
+ // CHECK-LABEL: define{{( dso_local)?}} void @foo(
// CHECK: br i1 %{{.*}}, label %{{.*}}, label %{{.*}}, !prof ![[FOO:[0-9]+]]
if (N) {}
}
diff --git a/test/profile/instrprof-shared-gcov-flush.test b/test/profile/instrprof-shared-gcov-flush.test
new file mode 100644
index 000000000000..50292b6336c4
--- /dev/null
+++ b/test/profile/instrprof-shared-gcov-flush.test
@@ -0,0 +1,52 @@
+# This test fails on Mac (https://bugs.llvm.org/show_bug.cgi?id=38134)
+XFAIL: darwin
+
+RUN: mkdir -p %t.d
+RUN: cd %t.d
+
+RUN: %clang --coverage -o libfunc.so -fPIC -shared %S/Inputs/instrprof-shared-lib.c
+RUN: test -f instrprof-shared-lib.gcno
+
+# Test the case where we exit abruptly after calling __gcov_flush, which means we don't write out the counters at exit.
+RUN: %clang -DEXIT_ABRUPTLY -DSHARED_CALL_BEFORE_GCOV_FLUSH -DSHARED_CALL_AFTER_GCOV_FLUSH --coverage -o %t -L%t.d -rpath %t.d -lfunc %S/Inputs/instrprof-shared-main-gcov-flush.c
+RUN: test -f instrprof-shared-main-gcov-flush.gcno
+
+RUN: %run %t
+RUN: llvm-cov gcov instrprof-shared-main-gcov-flush.gcda
+RUN: FileCheck --match-full-lines --strict-whitespace --input-file instrprof-shared-main-gcov-flush.c.gcov %S/Inputs/instrprof-shared-main-gcov-flush_no-writeout.c.gcov
+RUN: llvm-cov gcov instrprof-shared-lib.gcda
+RUN: FileCheck --match-full-lines --strict-whitespace --input-file instrprof-shared-lib.c.gcov %S/Inputs/instrprof-shared-lib.c.gcov
+RUN: rm instrprof-shared-main-gcov-flush.gcda instrprof-shared-lib.gcda
+
+# Test the case where we exit normally and we have a call to the shared library function before __gcov_flush.
+RUN: %clang -DSHARED_CALL_BEFORE_GCOV_FLUSH --coverage -o %t -L%t.d -rpath %t.d -lfunc %S/Inputs/instrprof-shared-main-gcov-flush.c
+RUN: test -f instrprof-shared-main-gcov-flush.gcno
+
+RUN: %run %t
+RUN: llvm-cov gcov instrprof-shared-main-gcov-flush.gcda
+RUN: FileCheck --match-full-lines --strict-whitespace --input-file instrprof-shared-main-gcov-flush.c.gcov %S/Inputs/instrprof-shared-main-gcov-flush_shared-call-before.c.gcov
+RUN: llvm-cov gcov instrprof-shared-lib.gcda
+RUN: FileCheck --match-full-lines --strict-whitespace --input-file instrprof-shared-lib.c.gcov %S/Inputs/instrprof-shared-lib.c.gcov
+RUN: rm instrprof-shared-main-gcov-flush.gcda instrprof-shared-lib.gcda
+
+# Test the case where we exit normally and we have a call to the shared library function after __gcov_flush.
+RUN: %clang -DSHARED_CALL_AFTER_GCOV_FLUSH --coverage -o %t -L%t.d -rpath %t.d -lfunc %S/Inputs/instrprof-shared-main-gcov-flush.c
+RUN: test -f instrprof-shared-main-gcov-flush.gcno
+
+RUN: %run %t
+RUN: llvm-cov gcov instrprof-shared-main-gcov-flush.gcda
+RUN: FileCheck --match-full-lines --strict-whitespace --input-file instrprof-shared-main-gcov-flush.c.gcov %S/Inputs/instrprof-shared-main-gcov-flush_shared-call-after.c.gcov
+RUN: llvm-cov gcov instrprof-shared-lib.gcda
+RUN: FileCheck --match-full-lines --strict-whitespace --input-file instrprof-shared-lib.c.gcov %S/Inputs/instrprof-shared-lib.c.gcov
+RUN: rm instrprof-shared-main-gcov-flush.gcda instrprof-shared-lib.gcda
+
+# Test the case where we exit normally and we have calls to the shared library function before and after __gcov_flush.
+RUN: %clang -DSHARED_CALL_BEFORE_GCOV_FLUSH -DSHARED_CALL_AFTER_GCOV_FLUSH --coverage -o %t -L%t.d -rpath %t.d -lfunc %S/Inputs/instrprof-shared-main-gcov-flush.c
+RUN: test -f instrprof-shared-main-gcov-flush.gcno
+
+RUN: %run %t
+RUN: llvm-cov gcov instrprof-shared-main-gcov-flush.gcda
+RUN: FileCheck --match-full-lines --strict-whitespace --input-file instrprof-shared-main-gcov-flush.c.gcov %S/Inputs/instrprof-shared-main-gcov-flush_shared-call-before-after.c.gcov
+RUN: llvm-cov gcov instrprof-shared-lib.gcda
+RUN: FileCheck --match-full-lines --strict-whitespace --input-file instrprof-shared-lib.c.gcov %S/Inputs/instrprof-shared-lib_called-twice.c.gcov
+RUN: rm instrprof-shared-main-gcov-flush.gcda instrprof-shared-lib.gcda
diff --git a/test/profile/instrprof-visibility.cpp b/test/profile/instrprof-visibility.cpp
index 6fbba9defc56..bb533050e059 100644
--- a/test/profile/instrprof-visibility.cpp
+++ b/test/profile/instrprof-visibility.cpp
@@ -1,8 +1,8 @@
// RUN: %clangxx_profgen -fcoverage-mapping %S/Inputs/instrprof-visibility-helper.cpp -o %t %s
// RUN: env LLVM_PROFILE_FILE=%t.profraw %run %t
// RUN: llvm-profdata merge %t.profraw -o %t.profdata
-// RUN: llvm-profdata show --all-functions %t.profraw | FileCheck %s --check-prefix=PROFILE
-// RUN: llvm-cov show %t -instr-profile=%t.profdata | FileCheck %s --check-prefix=COV
+// RUN: llvm-profdata show --all-functions %t.profraw | FileCheck -allow-deprecated-dag-overlap %s --check-prefix=PROFILE
+// RUN: llvm-cov show %t -instr-profile=%t.profdata | FileCheck -allow-deprecated-dag-overlap %s --check-prefix=COV
namespace {
#define NO_WEAK
diff --git a/test/sanitizer_common/CMakeLists.txt b/test/sanitizer_common/CMakeLists.txt
index 8b210a08aa57..4e2c80390f71 100644
--- a/test/sanitizer_common/CMakeLists.txt
+++ b/test/sanitizer_common/CMakeLists.txt
@@ -4,15 +4,17 @@ set(SANITIZER_COMMON_TEST_DEPS ${SANITIZER_COMMON_LIT_TEST_DEPS})
set(SANITIZER_COMMON_TESTSUITES)
set(SUPPORTED_TOOLS)
-if(CMAKE_SYSTEM_NAME MATCHES "Darwin|Linux|FreeBSD|NetBSD")
+if(CMAKE_SYSTEM_NAME MATCHES "Darwin|Linux|FreeBSD|NetBSD|SunOS")
list(APPEND SUPPORTED_TOOLS asan)
endif()
-if(CMAKE_SYSTEM_NAME MATCHES "Linux" AND NOT ANDROID)
+if(CMAKE_SYSTEM_NAME MATCHES "NetBSD" OR (CMAKE_SYSTEM_NAME MATCHES "Linux" AND NOT ANDROID))
list(APPEND SUPPORTED_TOOLS tsan)
list(APPEND SUPPORTED_TOOLS msan)
- list(APPEND SUPPORTED_TOOLS lsan)
list(APPEND SUPPORTED_TOOLS ubsan)
endif()
+if(CMAKE_SYSTEM_NAME MATCHES "Linux" AND NOT ANDROID)
+ list(APPEND SUPPORTED_TOOLS lsan)
+endif()
# Create a separate config for each tool we support.
foreach(tool ${SUPPORTED_TOOLS})
diff --git a/test/sanitizer_common/TestCases/Linux/aligned_alloc-alignment.cc b/test/sanitizer_common/TestCases/Linux/aligned_alloc-alignment.cc
new file mode 100644
index 000000000000..1a340edecdbe
--- /dev/null
+++ b/test/sanitizer_common/TestCases/Linux/aligned_alloc-alignment.cc
@@ -0,0 +1,43 @@
+// RUN: %clangxx %collect_stack_traces -O0 %s -o %t
+
+// Alignment is not a power of 2:
+// RUN: %env_tool_opts=allocator_may_return_null=0 not %run %t 17 2>&1 | FileCheck %s
+// Size is not a multiple of alignment:
+// RUN: %env_tool_opts=allocator_may_return_null=0 not %run %t 8 2>&1 | FileCheck %s
+// Alignment is 0:
+// RUN: %env_tool_opts=allocator_may_return_null=0 not %run %t 0 2>&1 | FileCheck %s
+
+// The same for allocator_may_return_null=1:
+// RUN: %env_tool_opts=allocator_may_return_null=1 %run %t 17 2>&1 | FileCheck %s --check-prefix=CHECK-NULL
+// RUN: %env_tool_opts=allocator_may_return_null=1 %run %t 8 2>&1 | FileCheck %s --check-prefix=CHECK-NULL
+// RUN: %env_tool_opts=allocator_may_return_null=1 %run %t 0 2>&1 | FileCheck %s --check-prefix=CHECK-NULL
+
+// REQUIRES: stable-runtime
+
+// UNSUPPORTED: android, ubsan
+
+#include <assert.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+extern void *aligned_alloc(size_t alignment, size_t size);
+
+int main(int argc, char **argv) {
+ assert(argc == 2);
+ const int alignment = atoi(argv[1]);
+
+ void *p = aligned_alloc(alignment, 100);
+ // CHECK: {{ERROR: .*Sanitizer: invalid alignment requested in aligned_alloc}}
+ // Handle a case when aligned_alloc is aliased by memalign.
+ // CHECK: {{#0 .*}}{{aligned_alloc|memalign}}
+ // CHECK: {{#1 .*main .*aligned_alloc-alignment.cc:}}[[@LINE-4]]
+ // CHECK: {{SUMMARY: .*Sanitizer: invalid-aligned-alloc-alignment}}
+
+ // The NULL pointer is printed differently on different systems, while (long)0
+ // is always the same.
+ fprintf(stderr, "errno: %d, p: %lx\n", errno, (long)p);
+ // CHECK-NULL: errno: 22, p: 0
+
+ return 0;
+}
diff --git a/test/sanitizer_common/TestCases/Linux/hard_rss_limit_mb_test.cc b/test/sanitizer_common/TestCases/Linux/hard_rss_limit_mb_test.cc
index 3c875c1793df..3013a3c3fd7d 100644
--- a/test/sanitizer_common/TestCases/Linux/hard_rss_limit_mb_test.cc
+++ b/test/sanitizer_common/TestCases/Linux/hard_rss_limit_mb_test.cc
@@ -16,6 +16,9 @@
// XFAIL: msan
// XFAIL: ubsan
+// https://github.com/google/sanitizers/issues/981
+// UNSUPPORTED: android-26
+
#include <string.h>
#include <stdio.h>
#include <unistd.h>
diff --git a/test/sanitizer_common/TestCases/Linux/mmap64_test.c b/test/sanitizer_common/TestCases/Linux/mmap64_test.c
new file mode 100644
index 000000000000..f4c009d846af
--- /dev/null
+++ b/test/sanitizer_common/TestCases/Linux/mmap64_test.c
@@ -0,0 +1,13 @@
+// RUN: %clang %s -o %t && %run %t
+
+#define _LARGEFILE64_SOURCE 1
+
+#include <assert.h>
+#include <sys/mman.h>
+
+int main() {
+ char *buf = (char *)mmap64(0, 100000, PROT_READ | PROT_WRITE,
+ MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+ assert(buf);
+ munmap(buf, 100000);
+}
diff --git a/test/sanitizer_common/TestCases/Linux/mmap_write_exec.cpp b/test/sanitizer_common/TestCases/Linux/mmap_write_exec.cpp
new file mode 100644
index 000000000000..49495403c5a1
--- /dev/null
+++ b/test/sanitizer_common/TestCases/Linux/mmap_write_exec.cpp
@@ -0,0 +1,37 @@
+// RUN: %clangxx %s -o %t
+// RUN: %env_tool_opts=detect_write_exec=1 %run %t 2>&1 | FileCheck %s
+// RUN: %env_tool_opts=detect_write_exec=0 %run %t 2>&1 | FileCheck %s \
+// RUN: --check-prefix=CHECK-DISABLED
+// ubsan and lsan do not install mmap interceptors UNSUPPORTED: ubsan, lsan
+
+// TODO: Fix option on Android, it hangs there for unknown reasons.
+// XFAIL: android
+
+#include <stdio.h>
+#include <sys/mman.h>
+
+int main(int argc, char **argv) {
+ char *p = (char *)mmap(0, 1024, PROT_READ | PROT_WRITE | PROT_EXEC,
+ MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
+ // CHECK: WARNING: {{.*}}Sanitizer: writable-executable page usage
+ // CHECK: #{{[0-9]+.*}}main{{.*}}mmap_write_exec.cpp:[[@LINE-3]]
+ // CHECK: SUMMARY: {{.*}}Sanitizer: w-and-x-usage
+
+ char *q = (char *)mmap(p, 64, PROT_READ | PROT_WRITE,
+ MAP_ANONYMOUS | MAP_PRIVATE | MAP_FIXED, -1, 0);
+ (void)mprotect(q, 64, PROT_WRITE | PROT_EXEC);
+ // CHECK: WARNING: {{.*}}Sanitizer: writable-executable page usage
+ // CHECK: #{{[0-9]+.*}}main{{.*}}mmap_write_exec.cpp:[[@LINE-2]]
+ // CHECK: SUMMARY: {{.*}}Sanitizer: w-and-x-usage
+
+ char *a = (char *)mmap(0, 1024, PROT_READ | PROT_WRITE,
+ MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
+ char *b = (char *)mmap(a, 64, PROT_READ | PROT_WRITE,
+ MAP_ANONYMOUS | MAP_PRIVATE | MAP_FIXED, -1, 0);
+ (void)mprotect(q, 64, PROT_READ | PROT_EXEC);
+ // CHECK-NOT: Sanitizer
+
+ printf("done\n");
+ // CHECK-DISABLED-NOT: Sanitizer
+ // CHECK-DISABLED: done
+}
diff --git a/test/sanitizer_common/TestCases/Linux/name_to_handle_at.cc b/test/sanitizer_common/TestCases/Linux/name_to_handle_at.cc
new file mode 100644
index 000000000000..47c6a18627a6
--- /dev/null
+++ b/test/sanitizer_common/TestCases/Linux/name_to_handle_at.cc
@@ -0,0 +1,21 @@
+// RUN: %clangxx -O0 %s -o %t && %run %t
+// UNSUPPORTED: android
+
+#include <assert.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+
+int main(int argc, char **argv) {
+ int mount_id;
+ struct file_handle *handle = reinterpret_cast<struct file_handle *>(
+ malloc(sizeof(*handle) + MAX_HANDLE_SZ));
+
+ handle->handle_bytes = MAX_HANDLE_SZ;
+ int res = name_to_handle_at(AT_FDCWD, argv[0], handle, &mount_id, 0);
+ assert(!res);
+
+ free(handle);
+ return 0;
+}
diff --git a/test/sanitizer_common/TestCases/Linux/pthread_mutex.cc b/test/sanitizer_common/TestCases/Linux/pthread_mutex.cc
new file mode 100644
index 000000000000..610958143b47
--- /dev/null
+++ b/test/sanitizer_common/TestCases/Linux/pthread_mutex.cc
@@ -0,0 +1,34 @@
+// RUN: %clangxx -O1 %s -o %t && %run %t
+// RUN: %clangxx -O1 -DUSE_GLIBC %s -o %t && %run %t
+// UNSUPPORTED: android
+
+#include <pthread.h>
+
+#ifdef USE_GLIBC
+extern "C" int __pthread_mutex_lock(pthread_mutex_t *__mutex);
+extern "C" int __pthread_mutex_unlock(pthread_mutex_t *__mutex);
+#define LOCK __pthread_mutex_lock
+#define UNLOCK __pthread_mutex_unlock
+#else
+#define LOCK pthread_mutex_lock
+#define UNLOCK pthread_mutex_unlock
+#endif
+
+pthread_mutex_t m = PTHREAD_MUTEX_INITIALIZER;
+int x;
+
+static void *Start(void *arg) {
+ LOCK(&m);
+ ++x;
+ UNLOCK(&m);
+ return nullptr;
+}
+
+int main() {
+ pthread_t threads[2] = {};
+ for (pthread_t &t : threads)
+ pthread_create(&t, 0, &Start, 0);
+ for (pthread_t &t : threads)
+ pthread_join(t, 0);
+ return 0;
+}
diff --git a/test/sanitizer_common/TestCases/Linux/pvalloc-overflow.cc b/test/sanitizer_common/TestCases/Linux/pvalloc-overflow.cc
new file mode 100644
index 000000000000..537c57e1a69f
--- /dev/null
+++ b/test/sanitizer_common/TestCases/Linux/pvalloc-overflow.cc
@@ -0,0 +1,47 @@
+// RUN: %clangxx %collect_stack_traces -O0 %s -o %t
+// RUN: %env_tool_opts=allocator_may_return_null=0 not %run %t m1 2>&1 | FileCheck %s
+// RUN: %env_tool_opts=allocator_may_return_null=1 %run %t m1 2>&1 | FileCheck %s --check-prefix=CHECK-NULL
+// RUN: %env_tool_opts=allocator_may_return_null=0 not %run %t psm1 2>&1 | FileCheck %s
+// RUN: %env_tool_opts=allocator_may_return_null=1 %run %t psm1 2>&1 | FileCheck %s --check-prefix=CHECK-NULL
+
+// REQUIRES: stable-runtime
+
+// UNSUPPORTED: android, freebsd, netbsd, ubsan
+
+// Checks that pvalloc overflows are caught. If the allocator is allowed to
+// return null, the errno should be set to ENOMEM.
+
+#include <assert.h>
+#include <errno.h>
+#include <malloc.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <string.h>
+#include <unistd.h>
+
+int main(int argc, char *argv[]) {
+ assert(argc == 2);
+ const char *action = argv[1];
+
+ const size_t page_size = sysconf(_SC_PAGESIZE);
+
+ void *p = nullptr;
+ if (!strcmp(action, "m1")) {
+ p = pvalloc((uintptr_t)-1);
+ } else if (!strcmp(action, "psm1")) {
+ p = pvalloc((uintptr_t)-(page_size - 1));
+ } else {
+ assert(0);
+ }
+ // CHECK: {{ERROR: .*Sanitizer: pvalloc parameters overflow: size .* rounded up to system page size .* cannot be represented in type size_t}}
+ // CHECK: {{#0 .*pvalloc}}
+ // CHECK: {{#1 .*main .*pvalloc-overflow.cc:}}
+ // CHECK: {{SUMMARY: .*Sanitizer: pvalloc-overflow}}
+
+ // The NULL pointer is printed differently on different systems, while (long)0
+ // is always the same.
+ fprintf(stderr, "errno: %d, p: %lx\n", errno, (long)p);
+ // CHECK-NULL: errno: 12, p: 0
+
+ return 0;
+}
diff --git a/test/sanitizer_common/TestCases/Linux/soft_rss_limit_mb_test.cc b/test/sanitizer_common/TestCases/Linux/soft_rss_limit_mb_test.cc
index 2ee809547530..f7d8b4d64016 100644
--- a/test/sanitizer_common/TestCases/Linux/soft_rss_limit_mb_test.cc
+++ b/test/sanitizer_common/TestCases/Linux/soft_rss_limit_mb_test.cc
@@ -15,6 +15,10 @@
// XFAIL: tsan
// XFAIL: msan
// XFAIL: ubsan
+
+// https://github.com/google/sanitizers/issues/981
+// UNSUPPORTED: android-26
+
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
@@ -65,4 +69,4 @@ int main() {
// CHECK_MAY_RETURN_0: allocating 128 times
// CHECK_MAY_RETURN_0: Some of the malloc calls returned non-null: 128
// CHECK_MAY_RETURN_0: allocating 256 times
-// CHECK_MAY_RETURN_0: allocator is terminating the process instead of returning
+// CHECK_MAY_RETURN_0: {{SUMMARY: .*Sanitizer: rss-limit-exceeded}}
diff --git a/test/sanitizer_common/TestCases/Linux/sysconf_interceptor_bypass_test.cc b/test/sanitizer_common/TestCases/Linux/sysconf_interceptor_bypass_test.cc
index c3a656022897..0ffb346ebb45 100644
--- a/test/sanitizer_common/TestCases/Linux/sysconf_interceptor_bypass_test.cc
+++ b/test/sanitizer_common/TestCases/Linux/sysconf_interceptor_bypass_test.cc
@@ -1,12 +1,14 @@
// RUN: %clangxx -O2 %s -o %t && %run %t 2>&1 | FileCheck %s
-// XFAIL: android
-
#include <stdio.h>
+#if !defined(__GLIBC_PREREQ)
+#define __GLIBC_PREREQ(a, b) 0
+#endif
+
// getauxval() used instead of sysconf() in GetPageSize() is defined starting
// glbc version 2.16.
-#if defined(__GLIBC_PREREQ) && __GLIBC_PREREQ(2, 16)
+#if __GLIBC_PREREQ(2, 16)
extern "C" long sysconf(int name) {
fprintf(stderr, "sysconf wrapper called\n");
return 0;
diff --git a/test/sanitizer_common/TestCases/NetBSD/faccessat.cc b/test/sanitizer_common/TestCases/NetBSD/faccessat.cc
new file mode 100644
index 000000000000..ae8be1962b8c
--- /dev/null
+++ b/test/sanitizer_common/TestCases/NetBSD/faccessat.cc
@@ -0,0 +1,6 @@
+// RUN: %clangxx -O0 -g %s -o %t && %run %t
+
+#include <fcntl.h>
+#include <unistd.h>
+
+int main(void) { return faccessat(AT_FDCWD, "/root", F_OK, 0); }
diff --git a/test/sanitizer_common/TestCases/NetBSD/getgrouplist.cc b/test/sanitizer_common/TestCases/NetBSD/getgrouplist.cc
new file mode 100644
index 000000000000..49655542ec6d
--- /dev/null
+++ b/test/sanitizer_common/TestCases/NetBSD/getgrouplist.cc
@@ -0,0 +1,29 @@
+// RUN: %clangxx -O0 -g %s -o %t && %run %t
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <grp.h>
+
+int main(void) {
+ gid_t *groups;
+ gid_t nobody;
+ int ngroups;
+
+ ngroups = sysconf(_SC_NGROUPS_MAX);
+ groups = (gid_t *)malloc(ngroups * sizeof(gid_t));
+ if (!groups)
+ exit(1);
+
+ if (gid_from_group("nobody", &nobody) == -1)
+ exit(1);
+
+ if (getgrouplist("nobody", nobody, groups, &ngroups))
+ exit(1);
+
+ if (groups && ngroups) {
+ free(groups);
+ exit(0);
+ }
+
+ return -1;
+}
diff --git a/test/sanitizer_common/TestCases/NetBSD/getgroupmembership.cc b/test/sanitizer_common/TestCases/NetBSD/getgroupmembership.cc
new file mode 100644
index 000000000000..ee27ad6cf365
--- /dev/null
+++ b/test/sanitizer_common/TestCases/NetBSD/getgroupmembership.cc
@@ -0,0 +1,30 @@
+// RUN: %clangxx -O0 -g %s -o %t && %run %t
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <grp.h>
+
+int main(void) {
+ gid_t *groups;
+ gid_t nobody;
+ int ngroups;
+ int maxgrp;
+
+ maxgrp = sysconf(_SC_NGROUPS_MAX);
+ groups = (gid_t *)malloc(maxgrp * sizeof(gid_t));
+ if (!groups)
+ exit(1);
+
+ if (gid_from_group("nobody", &nobody) == -1)
+ exit(1);
+
+ if (getgroupmembership("nobody", nobody, groups, maxgrp, &ngroups))
+ exit(1);
+
+ if (groups && ngroups) {
+ free(groups);
+ exit(0);
+ }
+
+ return -1;
+}
diff --git a/test/sanitizer_common/TestCases/NetBSD/gid_from_group.cc b/test/sanitizer_common/TestCases/NetBSD/gid_from_group.cc
new file mode 100644
index 000000000000..c6a9bc97c1e8
--- /dev/null
+++ b/test/sanitizer_common/TestCases/NetBSD/gid_from_group.cc
@@ -0,0 +1,16 @@
+// RUN: %clangxx -O0 -g %s -o %t && %run %t
+
+#include <grp.h>
+#include <stdlib.h>
+
+int main(void) {
+ gid_t nobody;
+
+ if (gid_from_group("nobody", &nobody) == -1)
+ exit(1);
+
+ if (nobody)
+ exit(0);
+
+ return 0;
+}
diff --git a/test/sanitizer_common/TestCases/NetBSD/group_from_gid.cc b/test/sanitizer_common/TestCases/NetBSD/group_from_gid.cc
new file mode 100644
index 000000000000..eb39da7b2b50
--- /dev/null
+++ b/test/sanitizer_common/TestCases/NetBSD/group_from_gid.cc
@@ -0,0 +1,17 @@
+// RUN: %clangxx -O0 -g %s -o %t && %run %t
+
+#include <grp.h>
+#include <stdlib.h>
+#include <string.h>
+
+int main(void) {
+ const char *nobody;
+
+ if (!(nobody = group_from_gid(0, 0)))
+ exit(1);
+
+ if (strlen(nobody))
+ exit(0);
+
+ return 0;
+}
diff --git a/test/sanitizer_common/TestCases/NetBSD/lit.local.cfg b/test/sanitizer_common/TestCases/NetBSD/lit.local.cfg
new file mode 100644
index 000000000000..94023561ffe3
--- /dev/null
+++ b/test/sanitizer_common/TestCases/NetBSD/lit.local.cfg
@@ -0,0 +1,9 @@
+def getRoot(config):
+ if not config.parent:
+ return config
+ return getRoot(config.parent)
+
+root = getRoot(config)
+
+if root.host_os not in ['NetBSD']:
+ config.unsupported = True
diff --git a/test/sanitizer_common/TestCases/NetBSD/netent.cc b/test/sanitizer_common/TestCases/NetBSD/netent.cc
new file mode 100644
index 000000000000..b574a931082c
--- /dev/null
+++ b/test/sanitizer_common/TestCases/NetBSD/netent.cc
@@ -0,0 +1,84 @@
+// RUN: %clangxx -O0 -g %s -o %t && %run %t 2>&1 | FileCheck %s
+
+#include <inttypes.h>
+#include <netdb.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#define STRING_OR_NULL(x) ((x) ? (x) : "null")
+
+void test1() {
+ struct netent *ntp = getnetent();
+
+ printf("%s ", ntp->n_name);
+
+ for (char **cp = ntp->n_aliases; *cp != NULL; cp++)
+ printf("%s ", STRING_OR_NULL(*cp));
+
+ printf("%d ", ntp->n_addrtype);
+ printf("%" PRIu32 "\n", ntp->n_net);
+
+ endnetent();
+}
+
+void test2() {
+ struct netent *ntp = getnetbyname("loopback");
+
+ printf("%s ", ntp->n_name);
+
+ for (char **cp = ntp->n_aliases; *cp != NULL; cp++)
+ printf("%s ", STRING_OR_NULL(*cp));
+
+ printf("%d ", ntp->n_addrtype);
+ printf("%" PRIu32 "\n", ntp->n_net);
+
+ endnetent();
+}
+
+void test3() {
+ struct netent *ntp = getnetbyaddr(127, 2);
+
+ printf("%s ", ntp->n_name);
+
+ for (char **cp = ntp->n_aliases; *cp != NULL; cp++)
+ printf("%s ", STRING_OR_NULL(*cp));
+
+ printf("%d ", ntp->n_addrtype);
+ printf("%" PRIu32 "\n", ntp->n_net);
+
+ endnetent();
+}
+
+void test4() {
+ setnetent(1);
+
+ struct netent *ntp = getnetent();
+
+ printf("%s ", ntp->n_name);
+
+ for (char **cp = ntp->n_aliases; *cp != NULL; cp++)
+ printf("%s ", STRING_OR_NULL(*cp));
+
+ printf("%d ", ntp->n_addrtype);
+ printf("%" PRIu32 "\n", ntp->n_net);
+
+ endnetent();
+}
+
+int main(void) {
+ printf("netent\n");
+
+ test1();
+ test2();
+ test3();
+ test4();
+
+ // CHECK: netent
+ // CHECK: loopback 2 127
+ // CHECK: loopback 2 127
+ // CHECK: loopback 2 127
+ // CHECK: loopback 2 127
+
+ return 0;
+}
diff --git a/test/sanitizer_common/TestCases/NetBSD/paccept.cc b/test/sanitizer_common/TestCases/NetBSD/paccept.cc
new file mode 100644
index 000000000000..7d2eb4e85596
--- /dev/null
+++ b/test/sanitizer_common/TestCases/NetBSD/paccept.cc
@@ -0,0 +1,74 @@
+// RUN: %clangxx -O0 -g %s -o %t && %run %t
+
+#include <netinet/in.h>
+#include <sys/socket.h>
+#include <sys/wait.h>
+#include <signal.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+int main(void) {
+ int child;
+ int fd, sfd;
+ socklen_t len;
+ struct sockaddr_in server = {}, client = {};
+ sigset_t set;
+
+ child = fork();
+ if (child == 0) {
+ fd = socket(AF_INET, SOCK_STREAM, 0);
+ if (fd == -1)
+ _exit(1);
+
+ server.sin_family = AF_INET;
+ server.sin_addr.s_addr = INADDR_ANY;
+ server.sin_port = htons(2222);
+
+ if (connect(fd, (struct sockaddr *)&server, sizeof(server)) == -1)
+ _exit(1);
+
+ close(fd);
+
+ _exit(0);
+ }
+
+ fd = socket(AF_INET, SOCK_STREAM, 0);
+ if (fd == -1) {
+ kill(child, SIGKILL);
+ wait(NULL);
+ exit(1);
+ }
+
+ server.sin_family = AF_INET;
+ server.sin_addr.s_addr = INADDR_ANY;
+ server.sin_port = htons(2222);
+
+ if (bind(fd, (const struct sockaddr *)&server, sizeof(server)) == -1) {
+ kill(child, SIGKILL);
+ wait(NULL);
+ exit(1);
+ }
+
+ listen(fd, 3);
+
+ if (sigemptyset(&set) == -1) {
+ kill(child, SIGKILL);
+ wait(NULL);
+ exit(1);
+ }
+
+ len = sizeof(client);
+ sfd = paccept(fd, (struct sockaddr *)&client, &len, &set, SOCK_NONBLOCK);
+ if (sfd == -1) {
+ kill(child, SIGKILL);
+ wait(NULL);
+ exit(1);
+ }
+
+ wait(NULL);
+
+ close(sfd);
+ close(fd);
+
+ return 0;
+}
diff --git a/test/sanitizer_common/TestCases/NetBSD/protoent.cc b/test/sanitizer_common/TestCases/NetBSD/protoent.cc
new file mode 100644
index 000000000000..c88c6f904a49
--- /dev/null
+++ b/test/sanitizer_common/TestCases/NetBSD/protoent.cc
@@ -0,0 +1,89 @@
+// RUN: %clangxx -O0 -g %s -o %t && %run %t 2>&1 | FileCheck %s
+
+#include <netdb.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#define STRING_OR_NULL(x) ((x) ? (x) : "null")
+
+void test1() {
+ struct protoent *ptp = getprotoent();
+
+ printf("%s ", STRING_OR_NULL(ptp->p_name));
+
+ for (char **cp = ptp->p_aliases; *cp != NULL; cp++)
+ printf("%s ", STRING_OR_NULL(*cp));
+
+ printf("%d\n", ptp->p_proto);
+ endprotoent();
+}
+
+void test2() {
+ struct protoent *ptp = getprotobyname("icmp");
+
+ printf("%s ", STRING_OR_NULL(ptp->p_name));
+
+ for (char **cp = ptp->p_aliases; *cp != NULL; cp++)
+ printf("%s ", STRING_OR_NULL(*cp));
+
+ printf("%d\n", ptp->p_proto);
+ endprotoent();
+}
+
+void test3() {
+ struct protoent *ptp = getprotobynumber(1);
+
+ printf("%s ", STRING_OR_NULL(ptp->p_name));
+
+ for (char **cp = ptp->p_aliases; *cp != NULL; cp++)
+ printf("%s ", STRING_OR_NULL(*cp));
+
+ printf("%d\n", ptp->p_proto);
+ endprotoent();
+}
+
+void test4() {
+ setprotoent(1);
+ struct protoent *ptp = getprotobynumber(1);
+
+ ptp = getprotobynumber(2);
+
+ printf("%s ", STRING_OR_NULL(ptp->p_name));
+
+ for (char **cp = ptp->p_aliases; *cp != NULL; cp++)
+ printf("%s ", STRING_OR_NULL(*cp));
+
+ printf("%d\n", ptp->p_proto);
+ endprotoent();
+}
+
+void test5() {
+ struct protoent *ptp = getprotobyname("ttp");
+
+ printf("%s ", STRING_OR_NULL(ptp->p_name));
+
+ for (char **cp = ptp->p_aliases; *cp != NULL; cp++)
+ printf("%s ", STRING_OR_NULL(*cp));
+
+ printf("%d\n", ptp->p_proto);
+ endprotoent();
+}
+
+int main(void) {
+ printf("protoent\n");
+
+ test1();
+ test2();
+ test3();
+ test4();
+ test5();
+
+ // CHECK: protoent
+ // CHECK: hopopt HOPOPT 0
+ // CHECK: icmp ICMP 1
+ // CHECK: icmp ICMP 1
+ // CHECK: igmp IGMP 2
+ // CHECK: ttp TTP iptm IPTM 84
+
+ return 0;
+}
diff --git a/test/sanitizer_common/TestCases/NetBSD/strmode.cc b/test/sanitizer_common/TestCases/NetBSD/strmode.cc
new file mode 100644
index 000000000000..b8d7d8ccf5a2
--- /dev/null
+++ b/test/sanitizer_common/TestCases/NetBSD/strmode.cc
@@ -0,0 +1,20 @@
+// RUN: %clangxx -O0 -g %s -o %t && %run %t
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+int main(void) {
+ struct stat st;
+ char modep[15];
+
+ if (stat("/etc/hosts", &st))
+ exit(1);
+
+ strmode(st.st_mode, modep);
+
+ printf("%s\n", modep);
+
+ return 0;
+}
diff --git a/test/sanitizer_common/TestCases/NetBSD/ttyent.cc b/test/sanitizer_common/TestCases/NetBSD/ttyent.cc
new file mode 100644
index 000000000000..73bc0a5da56b
--- /dev/null
+++ b/test/sanitizer_common/TestCases/NetBSD/ttyent.cc
@@ -0,0 +1,70 @@
+// RUN: %clangxx -O0 -g %s -o %t && %run %t 2>&1 | FileCheck %s
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <ttyent.h>
+
+#define STRING_OR_NULL(x) ((x) ? (x) : "null")
+
+void test1() {
+ struct ttyent *typ = getttyent();
+
+ printf("%s %s %s %d %s %s %s\n", STRING_OR_NULL(typ->ty_name),
+ STRING_OR_NULL(typ->ty_getty), STRING_OR_NULL(typ->ty_type),
+ typ->ty_status, STRING_OR_NULL(typ->ty_window),
+ STRING_OR_NULL(typ->ty_comment), STRING_OR_NULL(typ->ty_class));
+
+ endttyent();
+}
+
+void test2() {
+ struct ttyent *typ = getttynam("console");
+
+ printf("%s %s %s %d %s %s %s\n", STRING_OR_NULL(typ->ty_name),
+ STRING_OR_NULL(typ->ty_getty), STRING_OR_NULL(typ->ty_type),
+ typ->ty_status, STRING_OR_NULL(typ->ty_window),
+ STRING_OR_NULL(typ->ty_comment), STRING_OR_NULL(typ->ty_class));
+
+ endttyent();
+}
+
+void test3() {
+ if (!setttyent())
+ exit(1);
+
+ struct ttyent *typ = getttyent();
+
+ printf("%s %s %s %d %s %s %s\n", STRING_OR_NULL(typ->ty_name),
+ STRING_OR_NULL(typ->ty_getty), STRING_OR_NULL(typ->ty_type),
+ typ->ty_status, STRING_OR_NULL(typ->ty_window),
+ STRING_OR_NULL(typ->ty_comment), STRING_OR_NULL(typ->ty_class));
+
+ endttyent();
+}
+
+void test4() {
+ if (!setttyentpath(_PATH_TTYS))
+ exit(1);
+
+ struct ttyent *typ = getttyent();
+
+ printf("%s %s %s %d %s %s %s\n", STRING_OR_NULL(typ->ty_name),
+ STRING_OR_NULL(typ->ty_getty), STRING_OR_NULL(typ->ty_type),
+ typ->ty_status, STRING_OR_NULL(typ->ty_window),
+ STRING_OR_NULL(typ->ty_comment), STRING_OR_NULL(typ->ty_class));
+
+ endttyent();
+}
+
+int main(void) {
+ printf("ttyent\n");
+
+ test1();
+ test2();
+ test3();
+ test4();
+
+ // CHECK: ttyent
+
+ return 0;
+}
diff --git a/test/sanitizer_common/TestCases/NetBSD/uid_from_user.cc b/test/sanitizer_common/TestCases/NetBSD/uid_from_user.cc
new file mode 100644
index 000000000000..4cc1366aad4b
--- /dev/null
+++ b/test/sanitizer_common/TestCases/NetBSD/uid_from_user.cc
@@ -0,0 +1,16 @@
+// RUN: %clangxx -O0 -g %s -o %t && %run %t
+
+#include <pwd.h>
+#include <stdlib.h>
+
+int main(void) {
+ uid_t nobody;
+
+ if (uid_from_user("nobody", &nobody) == -1)
+ exit(1);
+
+ if (nobody)
+ exit(0);
+
+ return 0;
+}
diff --git a/test/sanitizer_common/TestCases/NetBSD/user_from_uid.cc b/test/sanitizer_common/TestCases/NetBSD/user_from_uid.cc
new file mode 100644
index 000000000000..bb098525a476
--- /dev/null
+++ b/test/sanitizer_common/TestCases/NetBSD/user_from_uid.cc
@@ -0,0 +1,17 @@
+// RUN: %clangxx -O0 -g %s -o %t && %run %t
+
+#include <pwd.h>
+#include <stdlib.h>
+#include <string.h>
+
+int main(void) {
+ const char *nobody;
+
+ if (!(nobody = user_from_uid(0, 0)))
+ exit(1);
+
+ if (strlen(nobody))
+ exit(0);
+
+ return 0;
+}
diff --git a/test/sanitizer_common/TestCases/Posix/access.cc b/test/sanitizer_common/TestCases/Posix/access.cc
new file mode 100644
index 000000000000..8623645f8bdf
--- /dev/null
+++ b/test/sanitizer_common/TestCases/Posix/access.cc
@@ -0,0 +1,5 @@
+// RUN: %clangxx -O0 -g %s -o %t && %run %t
+
+#include <unistd.h>
+
+int main(void) { return access("/dev/null", F_OK); }
diff --git a/test/sanitizer_common/TestCases/Posix/devname.cc b/test/sanitizer_common/TestCases/Posix/devname.cc
new file mode 100644
index 000000000000..da4bb8853a12
--- /dev/null
+++ b/test/sanitizer_common/TestCases/Posix/devname.cc
@@ -0,0 +1,23 @@
+// RUN: %clangxx -O0 -g %s -o %t && %run %t 2>&1 | FileCheck %s
+// UNSUPPORTED: linux, solaris
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/stat.h>
+
+int main(void) {
+ struct stat st;
+ char *name;
+
+ if (stat("/dev/null", &st))
+ exit(1);
+
+ if (!(name = devname(st.st_rdev, S_ISCHR(st.st_mode) ? S_IFCHR : S_IFBLK)))
+ exit(1);
+
+ printf("%s\n", name);
+
+ // CHECK: null
+
+ return 0;
+}
diff --git a/test/sanitizer_common/TestCases/Posix/devname_r.cc b/test/sanitizer_common/TestCases/Posix/devname_r.cc
new file mode 100644
index 000000000000..826b7c92ef2f
--- /dev/null
+++ b/test/sanitizer_common/TestCases/Posix/devname_r.cc
@@ -0,0 +1,28 @@
+// RUN: %clangxx -O0 -g %s -o %t && %run %t 2>&1 | FileCheck %s
+// UNSUPPORTED: linux, solaris
+
+#include <sys/cdefs.h>
+#include <sys/stat.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+
+int main(void) {
+ struct stat st;
+ char name[100];
+ mode_t type;
+
+ if (stat("/dev/null", &st))
+ exit(1);
+
+ type = S_ISCHR(st.st_mode) ? S_IFCHR : S_IFBLK;
+
+ if (!devname_r(st.st_rdev, type, name, sizeof(name)))
+ exit(1);
+
+ printf("%s\n", name);
+
+ // CHECK: null
+
+ return 0;
+}
diff --git a/test/sanitizer_common/TestCases/Posix/fgetln.cc b/test/sanitizer_common/TestCases/Posix/fgetln.cc
new file mode 100644
index 000000000000..e98cf449a272
--- /dev/null
+++ b/test/sanitizer_common/TestCases/Posix/fgetln.cc
@@ -0,0 +1,24 @@
+// RUN: %clangxx -O0 -g %s -o %t && %run %t
+// UNSUPPORTED: linux
+
+#include <stdio.h>
+#include <stdlib.h>
+
+int main(void) {
+ FILE *fp;
+ size_t len;
+ char *s;
+
+ fp = fopen("/etc/hosts", "r");
+ if (!fp)
+ exit(1);
+
+ s = fgetln(fp, &len);
+
+ printf("%.*s\n", (int)len, s);
+
+ if (fclose(fp) == EOF)
+ exit(1);
+
+ return 0;
+}
diff --git a/test/sanitizer_common/TestCases/Posix/fgets.cc b/test/sanitizer_common/TestCases/Posix/fgets.cc
new file mode 100644
index 000000000000..8dde5cd1a84f
--- /dev/null
+++ b/test/sanitizer_common/TestCases/Posix/fgets.cc
@@ -0,0 +1,20 @@
+// RUN: %clangxx -g %s -o %t && %run %t
+
+#include <stdio.h>
+
+int main(int argc, char **argv) {
+ FILE *fp;
+ char buf[2];
+ char *s;
+
+ fp = fopen(argv[0], "r");
+ if (!fp)
+ return 1;
+
+ s = fgets(buf, sizeof(buf), fp);
+ if (!s)
+ return 2;
+
+ fclose(fp);
+ return 0;
+}
diff --git a/test/sanitizer_common/TestCases/Posix/fputs_puts.cc b/test/sanitizer_common/TestCases/Posix/fputs_puts.cc
new file mode 100644
index 000000000000..8e8f7d384e8c
--- /dev/null
+++ b/test/sanitizer_common/TestCases/Posix/fputs_puts.cc
@@ -0,0 +1,18 @@
+// RUN: %clangxx -g %s -o %t && %run %t | FileCheck %s
+// CHECK: {{^foobar$}}
+
+#include <stdio.h>
+
+int main(void) {
+ int r;
+
+ r = fputs("foo", stdout);
+ if (r < 0)
+ return 1;
+
+ r = puts("bar");
+ if (r < 0)
+ return 1;
+
+ return 0;
+}
diff --git a/test/sanitizer_common/TestCases/Posix/getpass.cc b/test/sanitizer_common/TestCases/Posix/getpass.cc
index b91a3d7d5264..bf198eff91d2 100644
--- a/test/sanitizer_common/TestCases/Posix/getpass.cc
+++ b/test/sanitizer_common/TestCases/Posix/getpass.cc
@@ -5,13 +5,19 @@
#include <assert.h>
#include <stdio.h>
-#include <unistd.h>
#include <string.h>
#if __linux__
#include <pty.h>
+#elif defined(__FreeBSD__)
+#include <libutil.h>
+#include <pwd.h>
+#include <sys/ioctl.h>
+#include <sys/termios.h>
+#include <sys/types.h>
#else
#include <util.h>
#endif
+#include <unistd.h>
int
main (int argc, char** argv)
diff --git a/test/sanitizer_common/TestCases/Posix/illegal_read_test.cc b/test/sanitizer_common/TestCases/Posix/illegal_read_test.cc
new file mode 100644
index 000000000000..9615d7132da5
--- /dev/null
+++ b/test/sanitizer_common/TestCases/Posix/illegal_read_test.cc
@@ -0,0 +1,15 @@
+// Test that there was an illegal READ memory access.
+// RUN: %clangxx -O0 %s -o %t && not %run %t 2>&1 | FileCheck %s
+
+// REQUIRES: stable-runtime
+// XFAIL: powerpc64, s390x
+
+volatile int *null = 0;
+volatile int a;
+
+int main(int argc, char **argv) {
+ a = *null;
+ return 0;
+}
+
+// CHECK: The signal is caused by a READ memory access.
diff --git a/test/sanitizer_common/TestCases/Posix/illegal_write_test.cc b/test/sanitizer_common/TestCases/Posix/illegal_write_test.cc
new file mode 100644
index 000000000000..13d1c6a06905
--- /dev/null
+++ b/test/sanitizer_common/TestCases/Posix/illegal_write_test.cc
@@ -0,0 +1,14 @@
+// Test that there was an illegal WRITE memory access.
+// RUN: %clangxx -O0 %s -o %t && not %run %t 2>&1 | FileCheck %s
+
+// REQUIRES: stable-runtime
+// XFAIL: powerpc64, s390x
+
+volatile int *null = 0;
+
+int main(int argc, char **argv) {
+ *null = 0;
+ return 0;
+}
+
+// CHECK: The signal is caused by a WRITE memory access.
diff --git a/test/sanitizer_common/TestCases/Posix/lstat.cc b/test/sanitizer_common/TestCases/Posix/lstat.cc
new file mode 100644
index 000000000000..37237d82102c
--- /dev/null
+++ b/test/sanitizer_common/TestCases/Posix/lstat.cc
@@ -0,0 +1,16 @@
+// RUN: %clangxx -O0 -g %s -o %t && %run %t
+
+#include <stdlib.h>
+#include <sys/stat.h>
+
+int main(void) {
+ struct stat st;
+
+ if (lstat("/dev/null", &st))
+ exit(1);
+
+ if (!S_ISCHR(st.st_mode))
+ exit(1);
+
+ return 0;
+}
diff --git a/test/sanitizer_common/TestCases/Posix/mmap_test.c b/test/sanitizer_common/TestCases/Posix/mmap_test.c
new file mode 100644
index 000000000000..3c272f95a015
--- /dev/null
+++ b/test/sanitizer_common/TestCases/Posix/mmap_test.c
@@ -0,0 +1,11 @@
+// RUN: %clang %s -o %t && %run %t
+
+#include <assert.h>
+#include <sys/mman.h>
+
+int main() {
+ char *buf = (char *)mmap(0, 100000, PROT_READ | PROT_WRITE,
+ MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+ assert(buf);
+ munmap(buf, 100000);
+}
diff --git a/test/sanitizer_common/TestCases/Posix/posix_memalign-alignment.cc b/test/sanitizer_common/TestCases/Posix/posix_memalign-alignment.cc
new file mode 100644
index 000000000000..7729057d2deb
--- /dev/null
+++ b/test/sanitizer_common/TestCases/Posix/posix_memalign-alignment.cc
@@ -0,0 +1,47 @@
+// RUN: %clangxx %collect_stack_traces -O0 %s -o %t
+
+// Alignment is not a power of two:
+// RUN: %env_tool_opts=allocator_may_return_null=0 not %run %t 17 2>&1 | FileCheck %s
+// Alignment is not a power of two, although is a multiple of sizeof(void*):
+// RUN: %env_tool_opts=allocator_may_return_null=0 not %run %t 24 2>&1 | FileCheck %s
+// Alignment is not a multiple of sizeof(void*), although is a power of 2:
+// RUN: %env_tool_opts=allocator_may_return_null=0 not %run %t 2 2>&1 | FileCheck %s
+// Alignment is 0:
+// RUN: %env_tool_opts=allocator_may_return_null=0 not %run %t 0 2>&1 | FileCheck %s
+
+// The same for allocator_may_return_null=1:
+// RUN: %env_tool_opts=allocator_may_return_null=1 %run %t 17 2>&1 | FileCheck %s --check-prefix=CHECK-NULL
+// RUN: %env_tool_opts=allocator_may_return_null=1 %run %t 24 2>&1 | FileCheck %s --check-prefix=CHECK-NULL
+// RUN: %env_tool_opts=allocator_may_return_null=1 %run %t 2 2>&1 | FileCheck %s --check-prefix=CHECK-NULL
+// RUN: %env_tool_opts=allocator_may_return_null=1 %run %t 0 2>&1 | FileCheck %s --check-prefix=CHECK-NULL
+
+// REQUIRES: stable-runtime
+
+// UNSUPPORTED: ubsan
+
+#include <assert.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+int main(int argc, char **argv) {
+ assert(argc == 2);
+ const int alignment = atoi(argv[1]);
+
+ void* const kInitialPtrValue = reinterpret_cast<void*>(0x2a);
+ void *p = kInitialPtrValue;
+
+ errno = 0;
+ int res = posix_memalign(&p, alignment, 100);
+ // CHECK: {{ERROR: .*Sanitizer: invalid alignment requested in posix_memalign}}
+ // CHECK: {{#0 .*posix_memalign}}
+ // CHECK: {{#1 .*main .*posix_memalign-alignment.cc:}}[[@LINE-3]]
+ // CHECK: {{SUMMARY: .*Sanitizer: invalid-posix-memalign-alignment}}
+
+ // The NULL pointer is printed differently on different systems, while (long)0
+ // is always the same.
+ fprintf(stderr, "errno: %d, res: %d, p: %lx\n", errno, res, (long)p);
+ // CHECK-NULL: errno: 0, res: 22, p: 2a
+
+ return 0;
+}
diff --git a/test/sanitizer_common/TestCases/Posix/readlink.c b/test/sanitizer_common/TestCases/Posix/readlink.c
new file mode 100644
index 000000000000..ef0a4fe358b0
--- /dev/null
+++ b/test/sanitizer_common/TestCases/Posix/readlink.c
@@ -0,0 +1,26 @@
+// RUN: %clang -O0 %s -o %t && %run %t
+
+#include <assert.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+int main(int argc, char **argv) {
+ char symlink_path[PATH_MAX];
+ snprintf(symlink_path, sizeof(symlink_path), "%s_%d.symlink", argv[0],
+ getpid());
+ remove(symlink_path);
+ int res = symlink(argv[0], symlink_path);
+ assert(!res);
+
+ char readlink_path[PATH_MAX];
+ ssize_t res2 = readlink(symlink_path, readlink_path, sizeof(readlink_path));
+ assert(res2 >= 0);
+ readlink_path[res2] = '\0';
+ assert(!strcmp(readlink_path, argv[0]));
+
+ return 0;
+}
diff --git a/test/sanitizer_common/TestCases/Posix/readlinkat.c b/test/sanitizer_common/TestCases/Posix/readlinkat.c
new file mode 100644
index 000000000000..0afb5efe6b5f
--- /dev/null
+++ b/test/sanitizer_common/TestCases/Posix/readlinkat.c
@@ -0,0 +1,26 @@
+// RUN: %clang -O0 %s -o %t && %run %t
+
+#include <assert.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+
+int main(int argc, char **argv) {
+ char symlink_path[PATH_MAX];
+ snprintf(symlink_path, sizeof(symlink_path), "%s_%d.symlink", argv[0],
+ getpid());
+ remove(symlink_path);
+ int res = symlink(argv[0], symlink_path);
+ assert(!res);
+
+ char readlinkat_path[PATH_MAX];
+ int res2 = readlinkat(AT_FDCWD, symlink_path, readlinkat_path,
+ sizeof(readlinkat_path));
+ assert(res2 >= 0);
+ readlinkat_path[res2] = '\0';
+ assert(!strcmp(readlinkat_path, argv[0]));
+
+ return 0;
+}
diff --git a/test/sanitizer_common/TestCases/Posix/sanitizer_set_death_callback_test.cc b/test/sanitizer_common/TestCases/Posix/sanitizer_set_death_callback_test.cc
index 8d2db364114a..54272b017504 100644
--- a/test/sanitizer_common/TestCases/Posix/sanitizer_set_death_callback_test.cc
+++ b/test/sanitizer_common/TestCases/Posix/sanitizer_set_death_callback_test.cc
@@ -2,12 +2,6 @@
// REQUIRES: stable-runtime
-// For standalone LSan on x86 we have a problem: compiler spills the address
-// of allocated at line 42 memory thus memory block allocated in Leak() function
-// ends up to be classified as reachable despite the fact we zero out 'sink' at
-// the last line of main function. The problem doesn't reproduce with ASan because
-// quarantine prohibits memory block reuse for different allocations.
-// XFAIL: lsan-x86
// XFAIL: ubsan
#include <sanitizer/common_interface_defs.h>
@@ -31,7 +25,10 @@ void MaybeInit(int *uninitialized) {
__attribute__((noinline))
void Leak() {
- sink = new char[100]; // trigger lsan report.
+ // Trigger lsan report. Two attempts in case the address of the first
+ // allocation remained on the stack.
+ sink = new char[100];
+ sink = new char[100];
}
int main(int argc, char **argv) {
diff --git a/test/sanitizer_common/TestCases/Posix/strlcat.cc b/test/sanitizer_common/TestCases/Posix/strlcat.cc
new file mode 100644
index 000000000000..bdabada76aa7
--- /dev/null
+++ b/test/sanitizer_common/TestCases/Posix/strlcat.cc
@@ -0,0 +1,54 @@
+// RUN: %clangxx -O0 -g %s -o %t && %run %t
+
+// UNSUPPORTED: linux
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+void test1() {
+ const char src[] = "abc";
+ char dst[7] = {'x', 'y', 'z', 0};
+ size_t len;
+
+ len = strlcat(dst, src, sizeof(dst));
+ printf("%s %zu ", dst, len);
+}
+
+void test2() {
+ const char src[] = "abc";
+ char dst[7] = {0};
+ size_t len;
+
+ len = strlcat(dst, src, sizeof(dst));
+ printf("%s %zu ", dst, len);
+}
+
+void test3() {
+ const char src[] = "abc";
+ char dst[4] = {'x', 'y', 'z', 0};
+ size_t len;
+
+ len = strlcat(dst, src, sizeof(dst));
+ printf("%s %zu ", dst, len);
+}
+
+void test4() {
+ const char src[] = "";
+ char dst[4] = {'x', 'y', 'z', 0};
+ size_t len;
+
+ len = strlcat(dst, src, sizeof(dst));
+ printf("%s %zu\n", dst, len);
+}
+
+int main(void) {
+ test1();
+ test2();
+ test3();
+ test4();
+
+ // CHECK: xyzabc 6 abc 3 xyz 3 xyz 3
+
+ return 0;
+}
diff --git a/test/sanitizer_common/TestCases/Posix/strlcpy.cc b/test/sanitizer_common/TestCases/Posix/strlcpy.cc
new file mode 100644
index 000000000000..83053911d965
--- /dev/null
+++ b/test/sanitizer_common/TestCases/Posix/strlcpy.cc
@@ -0,0 +1,54 @@
+// RUN: %clangxx -O0 -g %s -o %t && %run %t
+
+// UNSUPPORTED: linux
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+void test1() {
+ const char src[] = "abc";
+ char dst[7] = {'x', 'y', 'z', 0};
+ size_t len;
+
+ len = strlcpy(dst, src, sizeof(dst));
+ printf("%s %zu ", dst, len);
+}
+
+void test2() {
+ const char src[] = "abc";
+ char dst[7] = {0};
+ size_t len;
+
+ len = strlcat(dst, src, sizeof(dst));
+ printf("%s %zu ", dst, len);
+}
+
+void test3() {
+ const char src[] = "abc";
+ char dst[4] = {'x', 'y', 'z', 0};
+ size_t len;
+
+ len = strlcat(dst, src, sizeof(dst));
+ printf("%s %zu ", dst, len);
+}
+
+void test4() {
+ const char src[] = "";
+ char dst[4] = {'x', 'y', 'z', 0};
+ size_t len;
+
+ len = strlcat(dst, src, sizeof(dst));
+ printf("%s %zu\n", dst, len);
+}
+
+int main(void) {
+ test1();
+ test2();
+ test3();
+ test4();
+
+ // CHECK: abc 3 abc 3 xyz 3 0
+
+ return 0;
+}
diff --git a/test/sanitizer_common/TestCases/Posix/strxfrm.c b/test/sanitizer_common/TestCases/Posix/strxfrm.c
new file mode 100644
index 000000000000..c28eb65b7d4f
--- /dev/null
+++ b/test/sanitizer_common/TestCases/Posix/strxfrm.c
@@ -0,0 +1,20 @@
+// RUN: %clang -O0 %s -o %t && %run %t
+// UNSUPPORTED: darwin
+
+#include <assert.h>
+#include <locale.h>
+#include <wchar.h>
+
+int main(int argc, char **argv) {
+ char q[10];
+ size_t n = strxfrm(q, "abcdef", sizeof(q));
+ assert(n < sizeof(q));
+
+ char q2[10];
+ locale_t loc = newlocale(LC_ALL_MASK, "", (locale_t)0);
+ n = strxfrm_l(q2, L"qwerty", sizeof(q), loc);
+ assert(n < sizeof(q2));
+
+ freelocale(loc);
+ return 0;
+}
diff --git a/test/sanitizer_common/TestCases/Posix/wcsxfrm.c b/test/sanitizer_common/TestCases/Posix/wcsxfrm.c
new file mode 100644
index 000000000000..3e349c75f409
--- /dev/null
+++ b/test/sanitizer_common/TestCases/Posix/wcsxfrm.c
@@ -0,0 +1,20 @@
+// RUN: %clang -O0 %s -o %t && %run %t
+// UNSUPPORTED: darwin
+
+#include <assert.h>
+#include <locale.h>
+#include <wchar.h>
+
+int main(int argc, char **argv) {
+ wchar_t q[10];
+ size_t n = wcsxfrm(q, L"abcdef", sizeof(q) / sizeof(wchar_t));
+ assert(n < sizeof(q));
+
+ wchar_t q2[10];
+ locale_t loc = newlocale(LC_ALL_MASK, "", (locale_t)0);
+ n = wcsxfrm_l(q2, L"qwerty", sizeof(q) / sizeof(wchar_t), loc);
+ assert(n < sizeof(q2));
+
+ freelocale(loc);
+ return 0;
+}
diff --git a/test/sanitizer_common/TestCases/allocator_returns_null.cc b/test/sanitizer_common/TestCases/allocator_returns_null.cc
new file mode 100644
index 000000000000..9ecdfef9ffcd
--- /dev/null
+++ b/test/sanitizer_common/TestCases/allocator_returns_null.cc
@@ -0,0 +1,114 @@
+// Test the behavior of malloc/calloc/realloc/new when the allocation size
+// exceeds the sanitizer's allocator max allowed one.
+// By default (allocator_may_return_null=0) the process should crash. With
+// allocator_may_return_null=1 the allocator should return nullptr and set errno
+// to the appropriate error code.
+//
+// RUN: %clangxx -O0 %s -o %t
+// RUN: not %run %t malloc 2>&1 | FileCheck %s --check-prefix=CHECK-mCRASH
+// RUN: %env_tool_opts=allocator_may_return_null=0 not %run %t malloc 2>&1 \
+// RUN: | FileCheck %s --check-prefix=CHECK-mCRASH
+// RUN: %env_tool_opts=allocator_may_return_null=1 %run %t malloc 2>&1 \
+// RUN: | FileCheck %s --check-prefix=CHECK-NULL
+// RUN: %env_tool_opts=allocator_may_return_null=0 not %run %t calloc 2>&1 \
+// RUN: | FileCheck %s --check-prefix=CHECK-cCRASH
+// RUN: %env_tool_opts=allocator_may_return_null=1 %run %t calloc 2>&1 \
+// RUN: | FileCheck %s --check-prefix=CHECK-NULL
+// RUN: %env_tool_opts=allocator_may_return_null=0 not %run %t calloc-overflow 2>&1 \
+// RUN: | FileCheck %s --check-prefix=CHECK-coCRASH
+// RUN: %env_tool_opts=allocator_may_return_null=1 %run %t calloc-overflow 2>&1 \
+// RUN: | FileCheck %s --check-prefix=CHECK-NULL
+// RUN: %env_tool_opts=allocator_may_return_null=0 not %run %t realloc 2>&1 \
+// RUN: | FileCheck %s --check-prefix=CHECK-rCRASH
+// RUN: %env_tool_opts=allocator_may_return_null=1 %run %t realloc 2>&1 \
+// RUN: | FileCheck %s --check-prefix=CHECK-NULL
+// RUN: %env_tool_opts=allocator_may_return_null=0 not %run %t realloc-after-malloc 2>&1 \
+// RUN: | FileCheck %s --check-prefix=CHECK-mrCRASH
+// RUN: %env_tool_opts=allocator_may_return_null=1 %run %t realloc-after-malloc 2>&1 \
+// RUN: | FileCheck %s --check-prefix=CHECK-NULL
+// RUN: %env_tool_opts=allocator_may_return_null=0 not %run %t new 2>&1 \
+// RUN: | FileCheck %s --check-prefix=CHECK-nCRASH
+// RUN: %env_tool_opts=allocator_may_return_null=1 not %run %t new 2>&1 \
+// RUN: | FileCheck %s --check-prefix=CHECK-nCRASH-OOM
+// RUN: %env_tool_opts=allocator_may_return_null=0 not %run %t new-nothrow 2>&1 \
+// RUN: | FileCheck %s --check-prefix=CHECK-nnCRASH
+// RUN: %env_tool_opts=allocator_may_return_null=1 %run %t new-nothrow 2>&1 \
+// RUN: | FileCheck %s --check-prefix=CHECK-NULL
+
+// TODO(alekseyshl): win32 is disabled due to failing errno tests, fix it there.
+// UNSUPPORTED: ubsan, win32
+
+#include <assert.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <limits>
+#include <new>
+
+int main(int argc, char **argv) {
+ assert(argc == 2);
+ const char *action = argv[1];
+ fprintf(stderr, "%s:\n", action);
+
+ // The maximum value of all supported sanitizers (search for
+ // kMaxAllowedMallocSize). For ASan + LSan, ASan limit is used.
+ static const size_t kMaxAllowedMallocSizePlusOne =
+#if __LP64__ || defined(_WIN64)
+ (1ULL << 40) + 1;
+#else
+ (3UL << 30) + 1;
+#endif
+
+ void *x = nullptr;
+ if (!strcmp(action, "malloc")) {
+ x = malloc(kMaxAllowedMallocSizePlusOne);
+ } else if (!strcmp(action, "calloc")) {
+ x = calloc((kMaxAllowedMallocSizePlusOne / 4) + 1, 4);
+ } else if (!strcmp(action, "calloc-overflow")) {
+ volatile size_t kMaxSizeT = std::numeric_limits<size_t>::max();
+ size_t kArraySize = 4096;
+ volatile size_t kArraySize2 = kMaxSizeT / kArraySize + 10;
+ x = calloc(kArraySize, kArraySize2);
+ } else if (!strcmp(action, "realloc")) {
+ x = realloc(0, kMaxAllowedMallocSizePlusOne);
+ } else if (!strcmp(action, "realloc-after-malloc")) {
+ char *t = (char*)malloc(100);
+ *t = 42;
+ x = realloc(t, kMaxAllowedMallocSizePlusOne);
+ assert(*t == 42);
+ free(t);
+ } else if (!strcmp(action, "new")) {
+ x = operator new(kMaxAllowedMallocSizePlusOne);
+ } else if (!strcmp(action, "new-nothrow")) {
+ x = operator new(kMaxAllowedMallocSizePlusOne, std::nothrow);
+ } else {
+ assert(0);
+ }
+
+ // The NULL pointer is printed differently on different systems, while (long)0
+ // is always the same.
+ fprintf(stderr, "errno: %d, x: %lx\n", errno, (long)x);
+
+ return 0;
+}
+
+// CHECK-mCRASH: malloc:
+// CHECK-mCRASH: {{SUMMARY: .*Sanitizer: allocation-size-too-big}}
+// CHECK-cCRASH: calloc:
+// CHECK-cCRASH: {{SUMMARY: .*Sanitizer: allocation-size-too-big}}
+// CHECK-coCRASH: calloc-overflow:
+// CHECK-coCRASH: {{SUMMARY: .*Sanitizer: calloc-overflow}}
+// CHECK-rCRASH: realloc:
+// CHECK-rCRASH: {{SUMMARY: .*Sanitizer: allocation-size-too-big}}
+// CHECK-mrCRASH: realloc-after-malloc:
+// CHECK-mrCRASH: {{SUMMARY: .*Sanitizer: allocation-size-too-big}}
+// CHECK-nCRASH: new:
+// CHECK-nCRASH: {{SUMMARY: .*Sanitizer: allocation-size-too-big}}
+// CHECK-nCRASH-OOM: new:
+// CHECK-nCRASH-OOM: {{SUMMARY: .*Sanitizer: out-of-memory}}
+// CHECK-nnCRASH: new-nothrow:
+// CHECK-nnCRASH: {{SUMMARY: .*Sanitizer: allocation-size-too-big}}
+
+// CHECK-NULL: {{malloc|calloc|calloc-overflow|realloc|realloc-after-malloc|new-nothrow}}
+// CHECK-NULL: errno: 12, x: 0
diff --git a/test/sanitizer_common/TestCases/ctype.c b/test/sanitizer_common/TestCases/ctype.c
new file mode 100644
index 000000000000..37e0af89be6d
--- /dev/null
+++ b/test/sanitizer_common/TestCases/ctype.c
@@ -0,0 +1,89 @@
+// RUN: %clang %s -o %t && %run %t 2>&1 | FileCheck %s
+
+#include <ctype.h>
+#include <limits.h>
+#include <locale.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+void check_ctype(void) {
+ unsigned char c;
+ volatile size_t i = 0; /* a dummy variable to prevent optimizing code out */
+
+ for (c = 0; c < UCHAR_MAX; c++)
+ i += !!isalpha(c);
+ for (c = 0; c < UCHAR_MAX; c++)
+ i += !!isascii(c);
+ for (c = 0; c < UCHAR_MAX; c++)
+ i += !!isblank(c);
+ for (c = 0; c < UCHAR_MAX; c++)
+ i += !!iscntrl(c);
+ for (c = 0; c < UCHAR_MAX; c++)
+ i += !!isdigit(c);
+ for (c = 0; c < UCHAR_MAX; c++)
+ i += !!isgraph(c);
+ for (c = 0; c < UCHAR_MAX; c++)
+ i += !!islower(c);
+ for (c = 0; c < UCHAR_MAX; c++)
+ i += !!isprint(c);
+ for (c = 0; c < UCHAR_MAX; c++)
+ i += !!ispunct(c);
+ for (c = 0; c < UCHAR_MAX; c++)
+ i += !!isspace(c);
+ for (c = 0; c < UCHAR_MAX; c++)
+ i += !!isupper(c);
+ for (c = 0; c < UCHAR_MAX; c++)
+ i += !!isxdigit(c);
+ for (c = 0; c < UCHAR_MAX; c++)
+ i += !!isalnum(c);
+
+ for (c = 0; c < UCHAR_MAX; c++)
+ i += !!tolower(c);
+ for (c = 0; c < UCHAR_MAX; c++)
+ i += !!toupper(c);
+
+ i += !!isalpha(EOF);
+ i += !!isascii(EOF);
+ i += !!isblank(EOF);
+ i += !!iscntrl(EOF);
+ i += !!isdigit(EOF);
+ i += !!isgraph(EOF);
+ i += !!islower(EOF);
+ i += !!isprint(EOF);
+ i += !!ispunct(EOF);
+ i += !!isspace(EOF);
+ i += !!isupper(EOF);
+ i += !!isxdigit(EOF);
+ i += !!isalnum(EOF);
+
+ i += !!tolower(EOF);
+ i += !!toupper(EOF);
+
+ if (i)
+ return;
+ else
+ return;
+}
+
+int main(int argc, char **argv) {
+ check_ctype();
+
+ setlocale(LC_ALL, "");
+
+ check_ctype();
+
+ setlocale(LC_ALL, "en_US.UTF-8");
+
+ check_ctype();
+
+ setlocale(LC_CTYPE, "pl_PL.UTF-8");
+
+ check_ctype();
+
+ printf("OK\n");
+
+ // CHECK: OK
+
+ return 0;
+}
diff --git a/test/sanitizer_common/TestCases/get_module_and_offset_for_pc.cc b/test/sanitizer_common/TestCases/get_module_and_offset_for_pc.cc
index 69ccb7234fab..0591d356f136 100644
--- a/test/sanitizer_common/TestCases/get_module_and_offset_for_pc.cc
+++ b/test/sanitizer_common/TestCases/get_module_and_offset_for_pc.cc
@@ -1,5 +1,6 @@
-// RUN: %clangxx -DSHARED %s -shared -o %T/get_module_and_offset_for_pc.so -fPIC
-// RUN: %clangxx -DSO_DIR=\"%T\" -O0 %s -ldl -o %t
+// RUN: mkdir -p %t-dir
+// RUN: %clangxx -DSHARED %s -shared -o %t-dir/get_module_and_offset_for_pc.so -fPIC
+// RUN: %clangxx -DSO_DIR=\"%t-dir\" -O0 %s -ldl -o %t
// RUN: %run %t 2>&1 | FileCheck %s
// UNSUPPORTED: i386-darwin
diff --git a/test/sanitizer_common/ios_commands/iossim_prepare.py b/test/sanitizer_common/ios_commands/iossim_prepare.py
new file mode 100755
index 000000000000..4b618fe9de8a
--- /dev/null
+++ b/test/sanitizer_common/ios_commands/iossim_prepare.py
@@ -0,0 +1,5 @@
+#!/usr/bin/python
+
+import os, sys, subprocess, json
+
+print(json.dumps({"env": {}}))
diff --git a/test/sanitizer_common/lit.common.cfg b/test/sanitizer_common/lit.common.cfg
index c7a1682f7404..1b347bf2bbac 100644
--- a/test/sanitizer_common/lit.common.cfg
+++ b/test/sanitizer_common/lit.common.cfg
@@ -6,6 +6,7 @@ config.test_source_root = os.path.join(os.path.dirname(__file__), "TestCases")
config.name = "SanitizerCommon-" + config.name_suffix
default_tool_options = []
+collect_stack_traces = ""
if config.tool_name == "asan":
tool_cflags = ["-fsanitize=address"]
tool_options = "ASAN_OPTIONS"
@@ -15,6 +16,7 @@ elif config.tool_name == "tsan":
elif config.tool_name == "msan":
tool_cflags = ["-fsanitize=memory"]
tool_options = "MSAN_OPTIONS"
+ collect_stack_traces = "-fsanitize-memory-track-origins"
elif config.tool_name == "lsan":
tool_cflags = ["-fsanitize=leak"]
tool_options = "LSAN_OPTIONS"
@@ -52,6 +54,7 @@ def build_invocation(compile_flags):
config.substitutions.append( ("%clang ", build_invocation(clang_cflags)) )
config.substitutions.append( ("%clangxx ", build_invocation(clang_cxxflags)) )
+config.substitutions.append( ("%collect_stack_traces", collect_stack_traces) )
config.substitutions.append( ("%tool_name", config.tool_name) )
config.substitutions.append( ("%tool_options", tool_options) )
config.substitutions.append( ('%env_tool_opts=',
@@ -59,5 +62,5 @@ config.substitutions.append( ('%env_tool_opts=',
config.suffixes = ['.c', '.cc', '.cpp']
-if config.host_os not in ['Linux', 'Darwin']:
+if config.host_os not in ['Linux', 'Darwin', 'NetBSD', 'FreeBSD']:
config.unsupported = True
diff --git a/test/scudo/aligned-new.cpp b/test/scudo/aligned-new.cpp
new file mode 100644
index 000000000000..0a10ae188c92
--- /dev/null
+++ b/test/scudo/aligned-new.cpp
@@ -0,0 +1,86 @@
+// RUN: %clangxx_scudo -std=c++1z -faligned-allocation %s -o %t
+// RUN: %run %t valid 2>&1
+// RUN: %env_scudo_opts=allocator_may_return_null=1 %run %t invalid 2>&1
+// RUN: %env_scudo_opts=allocator_may_return_null=0 not %run %t invalid 2>&1 | FileCheck %s
+
+// Tests that the C++17 aligned new/delete operators are working as expected.
+// Currently we do not check the consistency of the alignment on deallocation,
+// so this just tests that the APIs work.
+
+#include <assert.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <string.h>
+
+// Define all new/delete to not depend on the version provided by the platform.
+
+namespace std {
+struct nothrow_t {};
+static const nothrow_t nothrow;
+enum class align_val_t : size_t {};
+} // namespace std
+
+void *operator new(size_t);
+void *operator new[](size_t);
+void *operator new(size_t, std::nothrow_t const&);
+void *operator new[](size_t, std::nothrow_t const&);
+void *operator new(size_t, std::align_val_t);
+void *operator new[](size_t, std::align_val_t);
+void *operator new(size_t, std::align_val_t, std::nothrow_t const&);
+void *operator new[](size_t, std::align_val_t, std::nothrow_t const&);
+
+void operator delete(void*) throw();
+void operator delete[](void*) throw();
+void operator delete(void*, std::nothrow_t const&);
+void operator delete[](void*, std::nothrow_t const&);
+void operator delete(void*, size_t) throw();
+void operator delete[](void*, size_t) throw();
+void operator delete(void*, std::align_val_t) throw();
+void operator delete[](void*, std::align_val_t) throw();
+void operator delete(void*, std::align_val_t, std::nothrow_t const&);
+void operator delete[](void*, std::align_val_t, std::nothrow_t const&);
+void operator delete(void*, size_t, std::align_val_t) throw();
+void operator delete[](void*, size_t, std::align_val_t) throw();
+
+template<typename T>
+inline T* break_optimization(T *arg) {
+ __asm__ __volatile__("" : : "r" (arg) : "memory");
+ return arg;
+}
+
+struct S12 { int a, b, c; };
+struct alignas(128) S12_128 { int a, b, c; };
+struct alignas(256) S12_256 { int a, b, c; };
+struct alignas(512) S1024_512 { char a[1024]; };
+struct alignas(1024) S1024_1024 { char a[1024]; };
+
+int main(int argc, char **argv) {
+ assert(argc == 2);
+
+ if (!strcmp(argv[1], "valid")) {
+ // Standard use case.
+ delete break_optimization(new S12);
+ delete break_optimization(new S12_128);
+ delete[] break_optimization(new S12_128[4]);
+ delete break_optimization(new S12_256);
+ delete break_optimization(new S1024_512);
+ delete[] break_optimization(new S1024_512[4]);
+ delete break_optimization(new S1024_1024);
+
+ // Call directly the aligned versions of the operators.
+ const size_t alignment = 1U << 8;
+ void *p = operator new(1, static_cast<std::align_val_t>(alignment));
+ assert((reinterpret_cast<uintptr_t>(p) & (alignment - 1)) == 0);
+ operator delete(p, static_cast<std::align_val_t>(alignment));
+ }
+ if (!strcmp(argv[1], "invalid")) {
+ // Alignment must be a power of 2.
+ const size_t alignment = (1U << 8) - 1;
+ void *p = operator new(1, static_cast<std::align_val_t>(alignment),
+ std::nothrow);
+ // CHECK: Scudo ERROR: invalid allocation alignment
+ assert(!p);
+ }
+
+ return 0;
+}
diff --git a/test/scudo/alignment.c b/test/scudo/alignment.c
index 6235d50608db..4e2dc1af03b1 100644
--- a/test/scudo/alignment.c
+++ b/test/scudo/alignment.c
@@ -20,4 +20,4 @@ int main(int argc, char **argv)
return 0;
}
-// CHECK: ERROR: attempted to deallocate a chunk not properly aligned
+// CHECK: ERROR: misaligned pointer when deallocating address
diff --git a/test/scudo/double-free.cpp b/test/scudo/double-free.cpp
index 56118038cf1f..de6c90f1cced 100644
--- a/test/scudo/double-free.cpp
+++ b/test/scudo/double-free.cpp
@@ -2,7 +2,6 @@
// RUN: not %run %t malloc 2>&1 | FileCheck %s
// RUN: not %run %t new 2>&1 | FileCheck %s
// RUN: not %run %t newarray 2>&1 | FileCheck %s
-// RUN: not %run %t memalign 2>&1 | FileCheck %s
// Tests double-free error on pointers allocated with different allocation
// functions.
@@ -32,13 +31,6 @@ int main(int argc, char **argv)
delete[] p;
delete[] p;
}
- if (!strcmp(argv[1], "memalign")) {
- void *p = nullptr;
- posix_memalign(&p, 0x100, sizeof(int));
- assert(p);
- free(p);
- free(p);
- }
return 0;
}
diff --git a/test/scudo/fsanitize.c b/test/scudo/fsanitize.c
new file mode 100644
index 000000000000..7e5d5451f726
--- /dev/null
+++ b/test/scudo/fsanitize.c
@@ -0,0 +1,28 @@
+// Test various -fsanitize= additional flags combinations.
+
+// RUN: %clang_scudo %s -o %t
+// RUN: not %run %t 2>&1 | FileCheck %s
+
+// RUN: %clang_scudo -shared-libsan %s -o %t
+// RUN: env LD_LIBRARY_PATH=`dirname %shared_libscudo`:$LD_LIBRARY_PATH not %run %t 2>&1 | FileCheck %s
+// RUN: %clang_scudo -shared-libsan -fsanitize-minimal-runtime %s -o %t
+// RUN: env LD_LIBRARY_PATH=`dirname %shared_minlibscudo`:$LD_LIBRARY_PATH not %run %t 2>&1 | FileCheck %s
+
+// RUN: %clang_scudo -static-libsan %s -o %t
+// RUN: not %run %t 2>&1 | FileCheck %s
+// RUN: %clang_scudo -static-libsan -fsanitize-minimal-runtime %s -o %t
+// RUN: not %run %t 2>&1 | FileCheck %s
+
+#include <assert.h>
+#include <stdlib.h>
+
+int main(int argc, char *argv[]) {
+ unsigned long *p = (unsigned long *)malloc(sizeof(unsigned long));
+ assert(p);
+ *p = 0;
+ free(p);
+ free(p);
+ return 0;
+}
+
+// CHECK: ERROR: invalid chunk state
diff --git a/test/scudo/interface.cpp b/test/scudo/interface.cpp
index 73ea0a738e43..ec7375193e12 100644
--- a/test/scudo/interface.cpp
+++ b/test/scudo/interface.cpp
@@ -4,7 +4,6 @@
// RUN: %run %t heap-size 2>&1
// RUN: %env_scudo_opts="allocator_may_return_null=1" %run %t soft-limit 2>&1
// RUN: %env_scudo_opts="allocator_may_return_null=1" not %run %t hard-limit 2>&1
-// UNSUPPORTED: armhf-linux
// Tests that the sanitizer interface functions behave appropriately.
@@ -51,8 +50,11 @@ int main(int argc, char **argv)
// Verifies that setting the soft RSS limit at runtime works as expected.
std::vector<void *> pointers;
size_t size = 1 << 19; // 512Kb
- for (int i = 0; i < 5; i++)
- pointers.push_back(malloc(size));
+ for (int i = 0; i < 5; i++) {
+ void *p = malloc(size);
+ memset(p, 0, size);
+ pointers.push_back(p);
+ }
// Set the soft RSS limit to 1Mb.
__scudo_set_rss_limit(1, 0);
usleep(20000);
@@ -74,8 +76,11 @@ int main(int argc, char **argv)
// Verifies that setting the hard RSS limit at runtime works as expected.
std::vector<void *> pointers;
size_t size = 1 << 19; // 512Kb
- for (int i = 0; i < 5; i++)
- pointers.push_back(malloc(size));
+ for (int i = 0; i < 5; i++) {
+ void *p = malloc(size);
+ memset(p, 0, size);
+ pointers.push_back(p);
+ }
// Set the hard RSS limit to 1Mb
__scudo_set_rss_limit(1, 1);
usleep(20000);
diff --git a/test/scudo/lit.cfg b/test/scudo/lit.cfg
index 028bf721b89e..df78d5f9d6ad 100644
--- a/test/scudo/lit.cfg
+++ b/test/scudo/lit.cfg
@@ -8,16 +8,12 @@ config.name = 'Scudo' + config.name_suffix
# Setup source root.
config.test_source_root = os.path.dirname(__file__)
-# Path to the shared & static libraries
-shared_libscudo = os.path.join(config.compiler_rt_libdir, "libclang_rt.scudo-%s.so" % config.target_arch)
-static_libscudo = os.path.join(config.compiler_rt_libdir, "libclang_rt.scudo-%s.a" % config.target_arch)
-static_libscudo_cxx = os.path.join(config.compiler_rt_libdir, "libclang_rt.scudo_cxx-%s.a" % config.target_arch)
-
-whole_archive = "-Wl,-whole-archive %s -Wl,-no-whole-archive " % static_libscudo
-whole_archive_cxx = "-Wl,-whole-archive %s -Wl,-no-whole-archive " % static_libscudo_cxx
+# Path to the shared library
+shared_libscudo = os.path.join(config.compiler_rt_libdir, "libclang_rt.scudo%s.so" % config.target_suffix)
+shared_minlibscudo = os.path.join(config.compiler_rt_libdir, "libclang_rt.scudo_minimal-%s.so" % config.target_arch)
# Test suffixes.
-config.suffixes = ['.c', '.cc', '.cpp']
+config.suffixes = ['.c', '.cc', '.cpp', '.test']
# C & CXX flags.
c_flags = ([config.target_cflags] +
@@ -35,14 +31,17 @@ if not config.android:
cxx_flags = (c_flags + config.cxx_mode_flags + ["-std=c++11"])
-def build_invocation(compile_flags):
+scudo_flags = ["-fsanitize=scudo"]
+
+def build_invocation(compile_flags):
return " " + " ".join([config.clang] + compile_flags) + " "
-# Add clang substitutions.
+# Add substitutions.
config.substitutions.append(("%clang ", build_invocation(c_flags)))
-config.substitutions.append(("%clang_scudo ", build_invocation(c_flags) + whole_archive))
-config.substitutions.append(("%clangxx_scudo ", build_invocation(cxx_flags) + whole_archive + whole_archive_cxx))
+config.substitutions.append(("%clang_scudo ", build_invocation(c_flags + scudo_flags)))
+config.substitutions.append(("%clangxx_scudo ", build_invocation(cxx_flags + scudo_flags)))
config.substitutions.append(("%shared_libscudo", shared_libscudo))
+config.substitutions.append(("%shared_minlibscudo", shared_minlibscudo))
# Platform-specific default SCUDO_OPTIONS for lit tests.
default_scudo_opts = ''
diff --git a/test/scudo/memalign.c b/test/scudo/memalign.c
index 1fe6e3ec7eed..675f53415193 100644
--- a/test/scudo/memalign.c
+++ b/test/scudo/memalign.c
@@ -1,7 +1,10 @@
// RUN: %clang_scudo %s -o %t
-// RUN: %run %t valid 2>&1
-// RUN: not %run %t invalid 2>&1
-// RUN: %env_scudo_opts=allocator_may_return_null=1 %run %t invalid 2>&1
+// RUN: %run %t valid 2>&1
+// RUN: not %run %t invalid 2>&1 | FileCheck --check-prefix=CHECK-align %s
+// RUN: %env_scudo_opts=allocator_may_return_null=1 %run %t invalid 2>&1
+// RUN: not %run %t double-free 2>&1 | FileCheck --check-prefix=CHECK-double-free %s
+// RUN: %env_scudo_opts=DeallocationTypeMismatch=1 not %run %t realloc 2>&1 | FileCheck --check-prefix=CHECK-realloc %s
+// RUN: %env_scudo_opts=DeallocationTypeMismatch=0 %run %t realloc 2>&1
// Tests that the various aligned allocation functions work as intended. Also
// tests for the condition where the alignment is not a power of 2.
@@ -51,6 +54,7 @@ int main(int argc, char **argv)
// For larger alignment, reduce the number of allocations to avoid running
// out of potential addresses (on 32-bit).
for (int i = 19; i <= 24; i++) {
+ alignment = 1U << i;
for (int k = 0; k < 3; k++) {
p = memalign(alignment, 0x1000 - (2 * sizeof(void *) * k));
assert(p);
@@ -62,6 +66,7 @@ int main(int argc, char **argv)
if (!strcmp(argv[1], "invalid")) {
// Alignment is not a power of 2.
p = memalign(alignment - 1, size);
+ // CHECK-align: Scudo ERROR: invalid allocation alignment
assert(!p);
// Size is not a multiple of alignment.
p = aligned_alloc(alignment, size >> 1);
@@ -77,5 +82,22 @@ int main(int argc, char **argv)
assert(p == p_unchanged);
assert(err == EINVAL);
}
+ if (!strcmp(argv[1], "double-free")) {
+ void *p = NULL;
+ posix_memalign(&p, 0x100, sizeof(int));
+ assert(p);
+ free(p);
+ free(p);
+ }
+ if (!strcmp(argv[1], "realloc")) {
+ // We cannot reallocate a memalign'd chunk.
+ void *p = memalign(16, 16);
+ assert(p);
+ p = realloc(p, 32);
+ free(p);
+ }
return 0;
}
+
+// CHECK-double-free: ERROR: invalid chunk state
+// CHECK-realloc: ERROR: allocation type mismatch when reallocating address
diff --git a/test/scudo/mismatch.cpp b/test/scudo/mismatch.cpp
index b49e0ea46f12..b794f66d8a4e 100644
--- a/test/scudo/mismatch.cpp
+++ b/test/scudo/mismatch.cpp
@@ -1,18 +1,13 @@
// RUN: %clangxx_scudo %s -o %t
-// RUN: %env_scudo_opts=DeallocationTypeMismatch=1 not %run %t mallocdel 2>&1 | FileCheck --check-prefix=CHECK-dealloc %s
-// RUN: %env_scudo_opts=DeallocationTypeMismatch=0 %run %t mallocdel 2>&1
-// RUN: %env_scudo_opts=DeallocationTypeMismatch=1 not %run %t newfree 2>&1 | FileCheck --check-prefix=CHECK-dealloc %s
-// RUN: %env_scudo_opts=DeallocationTypeMismatch=0 %run %t newfree 2>&1
-// RUN: %env_scudo_opts=DeallocationTypeMismatch=1 not %run %t memaligndel 2>&1 | FileCheck --check-prefix=CHECK-dealloc %s
-// RUN: %env_scudo_opts=DeallocationTypeMismatch=0 %run %t memaligndel 2>&1
-// RUN: %env_scudo_opts=DeallocationTypeMismatch=1 not %run %t memalignrealloc 2>&1 | FileCheck --check-prefix=CHECK-realloc %s
-// RUN: %env_scudo_opts=DeallocationTypeMismatch=0 %run %t memalignrealloc 2>&1
+// RUN: %env_scudo_opts=DeallocationTypeMismatch=1 not %run %t mallocdel 2>&1 | FileCheck --check-prefix=CHECK-dealloc %s
+// RUN: %env_scudo_opts=DeallocationTypeMismatch=0 %run %t mallocdel 2>&1
+// RUN: %env_scudo_opts=DeallocationTypeMismatch=1 not %run %t newfree 2>&1 | FileCheck --check-prefix=CHECK-dealloc %s
+// RUN: %env_scudo_opts=DeallocationTypeMismatch=0 %run %t newfree 2>&1
// Tests that type mismatches between allocation and deallocation functions are
// caught when the related option is set.
#include <assert.h>
-#include <malloc.h>
#include <stdlib.h>
#include <string.h>
@@ -29,17 +24,6 @@ int main(int argc, char **argv)
assert(p);
free((void *)p);
}
- if (!strcmp(argv[1], "memaligndel")) {
- int *p = (int *)memalign(16, 16);
- assert(p);
- delete p;
- }
- if (!strcmp(argv[1], "memalignrealloc")) {
- void *p = memalign(16, 16);
- assert(p);
- p = realloc(p, 32);
- free(p);
- }
return 0;
}
diff --git a/test/scudo/preload.cpp b/test/scudo/preload.cpp
index b41a70e472b3..7fa8df4c6931 100644
--- a/test/scudo/preload.cpp
+++ b/test/scudo/preload.cpp
@@ -1,7 +1,8 @@
// Test that the preloaded runtime works without linking the static library.
// RUN: %clang %s -lstdc++ -o %t
-// RUN: env LD_PRELOAD=%shared_libscudo not %run %t 2>&1 | FileCheck %s
+// RUN: env LD_PRELOAD=%shared_libscudo not %run %t 2>&1 | FileCheck %s
+// RUN: env LD_PRELOAD=%shared_minlibscudo not %run %t 2>&1 | FileCheck %s
// This way of setting LD_PRELOAD does not work with Android test runner.
// REQUIRES: !android
diff --git a/test/scudo/random_shuffle.cpp b/test/scudo/random_shuffle.cpp
index f886cb1504e1..b493a292944c 100644
--- a/test/scudo/random_shuffle.cpp
+++ b/test/scudo/random_shuffle.cpp
@@ -1,12 +1,12 @@
// RUN: %clangxx_scudo %s -o %t
-// RUN: rm -rf %T/random_shuffle_tmp_dir
-// RUN: mkdir %T/random_shuffle_tmp_dir
-// RUN: %run %t 100 > %T/random_shuffle_tmp_dir/out1
-// RUN: %run %t 100 > %T/random_shuffle_tmp_dir/out2
-// RUN: %run %t 10000 > %T/random_shuffle_tmp_dir/out1
-// RUN: %run %t 10000 > %T/random_shuffle_tmp_dir/out2
-// RUN: not diff %T/random_shuffle_tmp_dir/out?
-// RUN: rm -rf %T/random_shuffle_tmp_dir
+// RUN: rm -rf %t-dir/random_shuffle_tmp_dir
+// RUN: mkdir -p %t-dir/random_shuffle_tmp_dir
+// RUN: %run %t 100 > %t-dir/random_shuffle_tmp_dir/out1
+// RUN: %run %t 100 > %t-dir/random_shuffle_tmp_dir/out2
+// RUN: %run %t 10000 > %t-dir/random_shuffle_tmp_dir/out1
+// RUN: %run %t 10000 > %t-dir/random_shuffle_tmp_dir/out2
+// RUN: not diff %t-dir/random_shuffle_tmp_dir/out?
+// RUN: rm -rf %t-dir/random_shuffle_tmp_dir
// Tests that the allocator shuffles the chunks before returning to the user.
diff --git a/test/scudo/realloc.cpp b/test/scudo/realloc.cpp
index 254c67a2cca4..26f6373b918e 100644
--- a/test/scudo/realloc.cpp
+++ b/test/scudo/realloc.cpp
@@ -1,6 +1,6 @@
// RUN: %clangxx_scudo %s -lstdc++ -o %t
-// RUN: %run %t pointers 2>&1
-// RUN: %run %t contents 2>&1
+// RUN: %run %t pointers 2>&1
+// RUN: %run %t contents 2>&1
// RUN: %run %t usablesize 2>&1
// Tests that our reallocation function returns the same pointer when the
@@ -15,6 +15,8 @@
#include <vector>
+#include <sanitizer/allocator_interface.h>
+
int main(int argc, char **argv)
{
void *p, *old_p;
@@ -35,7 +37,7 @@ int main(int argc, char **argv)
if (p) free(p);
size += 16;
p = malloc(size);
- usable_size = malloc_usable_size(p);
+ usable_size = __sanitizer_get_allocated_size(p);
assert(usable_size >= size);
} while (usable_size == size);
for (int i = 0; i < usable_size; i++)
@@ -56,7 +58,7 @@ int main(int argc, char **argv)
if (!strcmp(argv[1], "pointers")) {
old_p = p = realloc(nullptr, size);
assert(p);
- size = malloc_usable_size(p);
+ size = __sanitizer_get_allocated_size(p);
// Our realloc implementation will return the same pointer if the size
// requested is lower than or equal to the usable size of the associated
// chunk.
diff --git a/test/scudo/sized-delete.cpp b/test/scudo/sized-delete.cpp
index 85df05e2f809..81151b097481 100644
--- a/test/scudo/sized-delete.cpp
+++ b/test/scudo/sized-delete.cpp
@@ -38,4 +38,4 @@ int main(int argc, char **argv)
return 0;
}
-// CHECK: ERROR: invalid sized delete on chunk at address
+// CHECK: ERROR: invalid sized delete when deallocating address
diff --git a/test/scudo/sizes.cpp b/test/scudo/sizes.cpp
index 73fc71f25c54..f7ccbebedc30 100644
--- a/test/scudo/sizes.cpp
+++ b/test/scudo/sizes.cpp
@@ -1,11 +1,11 @@
// RUN: %clangxx_scudo %s -lstdc++ -o %t
-// RUN: %env_scudo_opts=allocator_may_return_null=0 not %run %t malloc 2>&1 | FileCheck %s
+// RUN: %env_scudo_opts=allocator_may_return_null=0 not %run %t malloc 2>&1 | FileCheck %s --check-prefix=CHECK-max
// RUN: %env_scudo_opts=allocator_may_return_null=1 %run %t malloc 2>&1
-// RUN: %env_scudo_opts=allocator_may_return_null=0 not %run %t calloc 2>&1 | FileCheck %s
+// RUN: %env_scudo_opts=allocator_may_return_null=0 not %run %t calloc 2>&1 | FileCheck %s --check-prefix=CHECK-calloc
// RUN: %env_scudo_opts=allocator_may_return_null=1 %run %t calloc 2>&1
-// RUN: %env_scudo_opts=allocator_may_return_null=0 not %run %t new 2>&1 | FileCheck %s
-// RUN: %env_scudo_opts=allocator_may_return_null=1 not %run %t new 2>&1 | FileCheck %s
-// RUN: %env_scudo_opts=allocator_may_return_null=0 not %run %t new-nothrow 2>&1 | FileCheck %s
+// RUN: %env_scudo_opts=allocator_may_return_null=0 not %run %t new 2>&1 | FileCheck %s --check-prefix=CHECK-max
+// RUN: %env_scudo_opts=allocator_may_return_null=1 not %run %t new 2>&1 | FileCheck %s --check-prefix=CHECK-oom
+// RUN: %env_scudo_opts=allocator_may_return_null=0 not %run %t new-nothrow 2>&1 | FileCheck %s --check-prefix=CHECK-max
// RUN: %env_scudo_opts=allocator_may_return_null=1 %run %t new-nothrow 2>&1
// RUN: %run %t usable 2>&1
@@ -21,10 +21,10 @@
#include <limits>
#include <new>
+#include <sanitizer/allocator_interface.h>
+
int main(int argc, char **argv) {
assert(argc == 2);
- const char *action = argv[1];
- fprintf(stderr, "%s:\n", action);
#if __LP64__ || defined(_WIN64)
static const size_t kMaxAllowedMallocSize = 1ULL << 40;
@@ -34,32 +34,32 @@ int main(int argc, char **argv) {
static const size_t kChunkHeaderSize = 8;
#endif
- if (!strcmp(action, "malloc")) {
+ if (!strcmp(argv[1], "malloc")) {
void *p = malloc(kMaxAllowedMallocSize);
assert(!p);
p = malloc(kMaxAllowedMallocSize - kChunkHeaderSize);
assert(!p);
- } else if (!strcmp(action, "calloc")) {
+ } else if (!strcmp(argv[1], "calloc")) {
// Trigger an overflow in calloc.
size_t size = std::numeric_limits<size_t>::max();
void *p = calloc((size / 0x1000) + 1, 0x1000);
assert(!p);
- } else if (!strcmp(action, "new")) {
+ } else if (!strcmp(argv[1], "new")) {
void *p = operator new(kMaxAllowedMallocSize);
assert(!p);
- } else if (!strcmp(action, "new-nothrow")) {
+ } else if (!strcmp(argv[1], "new-nothrow")) {
void *p = operator new(kMaxAllowedMallocSize, std::nothrow);
assert(!p);
- } else if (!strcmp(action, "usable")) {
+ } else if (!strcmp(argv[1], "usable")) {
// Playing with the actual usable size of a chunk.
void *p = malloc(1007);
assert(p);
- size_t size = malloc_usable_size(p);
+ size_t size = __sanitizer_get_allocated_size(p);
assert(size >= 1007);
memset(p, 'A', size);
p = realloc(p, 2014);
assert(p);
- size = malloc_usable_size(p);
+ size = __sanitizer_get_allocated_size(p);
assert(size >= 2014);
memset(p, 'B', size);
free(p);
@@ -70,4 +70,6 @@ int main(int argc, char **argv) {
return 0;
}
-// CHECK: allocator is terminating the process
+// CHECK-max: {{Scudo ERROR: requested allocation size .* exceeds maximum supported size}}
+// CHECK-oom: Scudo ERROR: allocator is out of memory
+// CHECK-calloc: Scudo ERROR: calloc parameters overflow
diff --git a/test/scudo/stats.c b/test/scudo/stats.c
new file mode 100644
index 000000000000..e7cc78ff0d49
--- /dev/null
+++ b/test/scudo/stats.c
@@ -0,0 +1,21 @@
+// RUN: %clang_scudo %s -o %t
+// RUN: %run %t 2>&1 | FileCheck %s
+
+// Tests that the allocator stats printing function exists and outputs
+// "something". Currently that "something" is fairly nebulous, as the 32-bit
+// primary doesn't output anything, and for the 64-bit one it's highly dependent
+// on the size class map and potential library allocations. So keep it very
+// generic for now.
+
+#include <stdlib.h>
+
+#include <sanitizer/scudo_interface.h>
+
+int main(int argc, char **argv)
+{
+ free(malloc(1U));
+ __scudo_print_stats();
+ return 0;
+}
+
+// CHECK: Stats:
diff --git a/test/scudo/symbols.test b/test/scudo/symbols.test
new file mode 100644
index 000000000000..0425e62ba6af
--- /dev/null
+++ b/test/scudo/symbols.test
@@ -0,0 +1,8 @@
+UNSUPPORTED: android
+
+Verify that various functions are *not* present in the minimal binary. Presence
+of those symbols in the minimal runtime would mean that the split code made it
+back into the core Sanitizer runtime library.
+
+RUN: nm %shared_minlibscudo | not grep Symbolizer
+RUN: nm %shared_minlibscudo | not grep Coverage
diff --git a/test/scudo/valloc.c b/test/scudo/valloc.c
index 132c4f280220..605b9c4d4b9d 100644
--- a/test/scudo/valloc.c
+++ b/test/scudo/valloc.c
@@ -1,8 +1,8 @@
// RUN: %clang_scudo %s -o %t
// RUN: %run %t valid 2>&1
-// RUN: not %run %t invalid 2>&1
+// RUN: not %run %t invalid 2>&1 | FileCheck %s
// RUN: %env_scudo_opts=allocator_may_return_null=1 %run %t invalid 2>&1
-// UNSUPPORTED: android, armhf-linux
+// UNSUPPORTED: android
// Tests that valloc and pvalloc work as intended.
@@ -54,6 +54,7 @@ int main(int argc, char **argv)
if (!strcmp(argv[1], "invalid")) {
// Size passed to pvalloc overflows when rounded up.
p = pvalloc((size_t)-1);
+ // CHECK: Scudo ERROR: pvalloc parameters overflow
assert(!p);
assert(errno == ENOMEM);
errno = 0;
diff --git a/test/shadowcallstack/CMakeLists.txt b/test/shadowcallstack/CMakeLists.txt
new file mode 100644
index 000000000000..ab2b18819d49
--- /dev/null
+++ b/test/shadowcallstack/CMakeLists.txt
@@ -0,0 +1,21 @@
+set(TEST_ARCH ${SHADOWCALLSTACK_SUPPORTED_ARCH})
+
+set(SHADOWCALLSTACK_LIT_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR})
+set(SHADOWCALLSTACK_LIT_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR})
+
+set(SHADOWCALLSTACK_TEST_DEPS ${SANITIZER_COMMON_LIT_TEST_DEPS})
+
+foreach(arch ${SHADOWCALLSTACK_SUPPORTED_ARCH})
+ set(SANITIZER_COMMON_TEST_TARGET_ARCH ${arch})
+ get_test_cc_for_arch(${arch}
+ SHADOWSTACK_TEST_TARGET_CC SHADOWSTACK_TEST_TARGET_CFLAGS)
+ configure_lit_site_cfg(
+ ${CMAKE_CURRENT_SOURCE_DIR}/lit.site.cfg.in
+ ${CMAKE_CURRENT_BINARY_DIR}/${arch}/lit.site.cfg)
+ list(APPEND SHADOWCALLSTACK_TESTSUITES ${CMAKE_CURRENT_BINARY_DIR}/${arch})
+endforeach()
+
+add_lit_testsuite(check-shadowcallstack "Running the ShadowCallStack tests"
+ ${SHADOWCALLSTACK_TESTSUITES}
+ DEPENDS ${SANITIZER_COMMON_LIT_TEST_DEPS})
+set_target_properties(check-shadowcallstack PROPERTIES FOLDER "Compiler-RT Misc")
diff --git a/test/shadowcallstack/init.c b/test/shadowcallstack/init.c
new file mode 100644
index 000000000000..a406e1b140fc
--- /dev/null
+++ b/test/shadowcallstack/init.c
@@ -0,0 +1,12 @@
+// RUN: %clang_scs %s -o %t
+// RUN: %run %t
+
+// Basic smoke test for the runtime
+
+#include "libc_support.h"
+#include "minimal_runtime.h"
+
+int scs_main(void) {
+ scs_fputs_stdout("In main.\n");
+ return 0;
+}
diff --git a/test/shadowcallstack/libc_support.h b/test/shadowcallstack/libc_support.h
new file mode 100644
index 000000000000..5d89aab645a9
--- /dev/null
+++ b/test/shadowcallstack/libc_support.h
@@ -0,0 +1,41 @@
+// This header provides replacements for certain libc functions. It is necessary
+// in order to safely run the tests on aarch64, because the system libc might
+// not have been compiled with -ffixed-x18.
+
+#pragma once
+
+#include <stddef.h>
+#include <stdint.h>
+#include <stdio.h>
+
+#ifdef __aarch64__
+
+size_t scs_strlen(const char *p) {
+ size_t retval = 0;
+ while (*p++)
+ retval++;
+ return retval;
+}
+
+// We mark this function as noinline to make sure that its callers do not
+// become leaf functions as a result of inlining. This is because we want to
+// make sure that we generate the correct code for non-leaf functions.
+
+__attribute__((noinline)) void scs_fputs_stdout(const char *p) {
+ __asm__ __volatile__(
+ "mov x0, #1\n" // stdout
+ "mov x1, %0\n"
+ "mov x2, %1\n"
+ "mov x8, #64\n" // write
+ "svc #0\n" ::"r"(p),
+ "r"(scs_strlen(p))
+ : "x0", "x1", "x2", "x8");
+}
+
+#else
+
+__attribute__((noinline)) void scs_fputs_stdout(const char *p) {
+ fputs(p, stdout);
+}
+
+#endif
diff --git a/test/shadowcallstack/lit.cfg b/test/shadowcallstack/lit.cfg
new file mode 100644
index 000000000000..313cd2b8eff3
--- /dev/null
+++ b/test/shadowcallstack/lit.cfg
@@ -0,0 +1,23 @@
+# -*- Python -*-
+
+import os
+
+# Setup config name.
+config.name = 'ShadowCallStack'
+
+# Setup source root.
+config.test_source_root = os.path.dirname(__file__)
+
+# Test suffixes.
+config.suffixes = ['.c', '.cc', '.cpp', '.m', '.mm', '.ll', '.test']
+
+# Add clang substitutions.
+config.substitutions.append( ("%clang_noscs ", config.clang + ' -O0 -fno-sanitize=shadow-call-stack ' + config.target_cflags + ' ') )
+
+scs_arch_cflags = config.target_cflags
+if config.target_arch == 'aarch64':
+ scs_arch_cflags += ' -ffixed-x18 '
+config.substitutions.append( ("%clang_scs ", config.clang + ' -O0 -fsanitize=shadow-call-stack ' + scs_arch_cflags + ' ') )
+
+if config.host_os not in ['Linux'] or config.target_arch not in ['x86_64', 'aarch64']:
+ config.unsupported = True
diff --git a/test/shadowcallstack/lit.site.cfg.in b/test/shadowcallstack/lit.site.cfg.in
new file mode 100644
index 000000000000..aa8913e84cb8
--- /dev/null
+++ b/test/shadowcallstack/lit.site.cfg.in
@@ -0,0 +1,12 @@
+@LIT_SITE_CFG_IN_HEADER@
+
+# Tool-specific config options.
+config.name_suffix = "@SHADOWCALLSTACK_TEST_CONFIG_SUFFIX@"
+config.target_cflags = "@SHADOWCALLSTACK_TEST_TARGET_CFLAGS@"
+config.target_arch = "@SHADOWCALLSTACK_TEST_TARGET_ARCH@"
+
+# Load common config for all compiler-rt lit tests.
+lit_config.load_config(config, "@COMPILER_RT_BINARY_DIR@/test/lit.common.configured")
+
+# Load tool-specific config that would do the real work.
+lit_config.load_config(config, "@SHADOWCALLSTACK_LIT_SOURCE_DIR@/lit.cfg")
diff --git a/test/shadowcallstack/minimal_runtime.h b/test/shadowcallstack/minimal_runtime.h
new file mode 100644
index 000000000000..f36fa5a7d245
--- /dev/null
+++ b/test/shadowcallstack/minimal_runtime.h
@@ -0,0 +1,43 @@
+// A shadow call stack runtime is not yet included with compiler-rt, provide a
+// minimal runtime to allocate a shadow call stack and assign an
+// architecture-specific register to point at it.
+
+#pragma once
+
+#ifdef __x86_64__
+#include <asm/prctl.h>
+int arch_prctl(int code, void *addr);
+#endif
+#include <stdlib.h>
+#include <sys/mman.h>
+#include <sys/prctl.h>
+
+#include "libc_support.h"
+
+__attribute__((no_sanitize("shadow-call-stack")))
+static void __shadowcallstack_init() {
+ void *stack = mmap(NULL, 8192, PROT_READ | PROT_WRITE,
+ MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+ if (stack == MAP_FAILED)
+ abort();
+
+#if defined(__x86_64__)
+ if (arch_prctl(ARCH_SET_GS, stack))
+ abort();
+#elif defined(__aarch64__)
+ __asm__ __volatile__("mov x18, %0" ::"r"(stack));
+#else
+#error Unsupported platform
+#endif
+}
+
+int scs_main(void);
+
+__attribute__((no_sanitize("shadow-call-stack"))) int main(void) {
+ __shadowcallstack_init();
+
+ // We can't simply return scs_main() because scs_main might have corrupted our
+ // return address for testing purposes (see overflow.c), so we need to exit
+ // ourselves.
+ exit(scs_main());
+}
diff --git a/test/shadowcallstack/overflow-aarch64.c b/test/shadowcallstack/overflow-aarch64.c
new file mode 100644
index 000000000000..8da798164fe7
--- /dev/null
+++ b/test/shadowcallstack/overflow-aarch64.c
@@ -0,0 +1,5 @@
+// See overflow.c for a description.
+
+// REQUIRES: aarch64-target-arch
+// RUN: %clang_scs %S/overflow.c -o %t -DITERATIONS=12
+// RUN: %run %t | FileCheck %S/overflow.c
diff --git a/test/shadowcallstack/overflow-x86_64.c b/test/shadowcallstack/overflow-x86_64.c
new file mode 100644
index 000000000000..38bb13a969a3
--- /dev/null
+++ b/test/shadowcallstack/overflow-x86_64.c
@@ -0,0 +1,5 @@
+// See overflow.c for a description.
+
+// REQUIRES: x86_64-target-arch
+// RUN: %clang_scs %S/overflow.c -o %t -DITERATIONS=12
+// RUN: not --crash %run %t
diff --git a/test/shadowcallstack/overflow.c b/test/shadowcallstack/overflow.c
new file mode 100644
index 000000000000..8c3d50c5917f
--- /dev/null
+++ b/test/shadowcallstack/overflow.c
@@ -0,0 +1,39 @@
+// Test that a stack overflow fails as expected
+
+// RUN: %clang_noscs %s -o %t -DITERATIONS=3
+// RUN: %run %t | FileCheck %s
+// RUN: %clang_noscs %s -o %t -DITERATIONS=12
+// RUN: %run %t | FileCheck -check-prefix=OVERFLOW_SUCCESS %s
+
+// RUN: %clang_scs %s -o %t -DITERATIONS=3
+// RUN: %run %t | FileCheck %s
+
+// The behavioral check for SCS + overflow lives in the tests overflow-x86_64.c
+// and overflow-aarch64.c. This is because the expected behavior is different
+// between the two platforms. On x86_64 we crash because the comparison between
+// the shadow call stack and the regular stack fails. On aarch64 there is no
+// comparison, we just load the return address from the shadow call stack. So we
+// just expect not to see the output from print_and_exit.
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "minimal_runtime.h"
+
+void print_and_exit(void) {
+// CHECK-NOT: Stack overflow successful.
+// OVERFLOW_SUCCESS: Stack overflow successful.
+ scs_fputs_stdout("Stack overflow successful.\n");
+ exit(0);
+}
+
+int scs_main(void)
+{
+ void *addrs[4];
+ for (int i = 0; i < ITERATIONS; i++)
+ addrs[i] = &print_and_exit;
+
+ scs_fputs_stdout("Returning.\n");
+
+ return 0;
+}
diff --git a/test/tsan/CMakeLists.txt b/test/tsan/CMakeLists.txt
index 2b1d3004b1de..ba0fd9f23a33 100644
--- a/test/tsan/CMakeLists.txt
+++ b/test/tsan/CMakeLists.txt
@@ -24,10 +24,7 @@ if(APPLE)
endif()
foreach(arch ${TSAN_TEST_ARCH})
- set(TSAN_TEST_IOS "0")
- pythonize_bool(TSAN_TEST_IOS)
- set(TSAN_TEST_IOSSIM "0")
- pythonize_bool(TSAN_TEST_IOSSIM)
+ set(TSAN_TEST_APPLE_PLATFORM "osx")
set(TSAN_TEST_TARGET_ARCH ${arch})
string(TOLOWER "-${arch}" TSAN_TEST_CONFIG_SUFFIX)
@@ -51,15 +48,12 @@ if(APPLE)
set(EXCLUDE_FROM_ALL ON)
set(TSAN_TEST_TARGET_CC ${COMPILER_RT_TEST_COMPILER})
- set(TSAN_TEST_IOS "1")
- pythonize_bool(TSAN_TEST_IOS)
+ set(TSAN_TEST_APPLE_PLATFORM "iossim")
set(arch "x86_64")
- set(TSAN_TEST_IOSSIM "1")
- pythonize_bool(TSAN_TEST_IOSSIM)
set(TSAN_TEST_TARGET_ARCH ${arch})
set(TSAN_TEST_TARGET_CFLAGS "-arch ${arch} -isysroot ${DARWIN_iossim_SYSROOT} ${COMPILER_RT_TEST_COMPILER_CFLAGS}")
- set(TSAN_TEST_CONFIG_SUFFIX "-${arch}-iossim")
+ set(TSAN_TEST_CONFIG_SUFFIX "-${arch}-${TSAN_TEST_APPLE_PLATFORM}")
string(TOUPPER ${arch} ARCH_UPPER_CASE)
set(CONFIG_NAME "IOSSim${ARCH_UPPER_CASE}Config")
configure_lit_site_cfg(
@@ -70,12 +64,11 @@ if(APPLE)
${CMAKE_CURRENT_BINARY_DIR}/${CONFIG_NAME}/
DEPENDS ${TSAN_TEST_DEPS})
+ set(TSAN_TEST_APPLE_PLATFORM "ios")
set(arch "arm64")
- set(TSAN_TEST_IOSSIM "0")
- pythonize_bool(TSAN_TEST_IOSSIM)
set(TSAN_TEST_TARGET_ARCH ${arch})
set(TSAN_TEST_TARGET_CFLAGS "-arch ${arch} -isysroot ${DARWIN_ios_SYSROOT} ${COMPILER_RT_TEST_COMPILER_CFLAGS}")
- set(TSAN_TEST_CONFIG_SUFFIX "-${arch}-ios")
+ set(TSAN_TEST_CONFIG_SUFFIX "-${arch}-${TSAN_TEST_APPLE_PLATFORM}")
string(TOUPPER ${arch} ARCH_UPPER_CASE)
set(CONFIG_NAME "IOS${ARCH_UPPER_CASE}Config")
configure_lit_site_cfg(
diff --git a/test/tsan/Darwin/external-swift-debugging.cc b/test/tsan/Darwin/external-swift-debugging.cc
new file mode 100644
index 000000000000..603734e5d035
--- /dev/null
+++ b/test/tsan/Darwin/external-swift-debugging.cc
@@ -0,0 +1,68 @@
+// RUN: %clangxx_tsan %s -o %t
+// RUN: %deflake %run %t 2>&1 | FileCheck %s
+
+#include <thread>
+
+#import "../test.h"
+
+
+extern "C" {
+int __tsan_get_report_data(void *report, const char **description, int *count,
+ int *stack_count, int *mop_count, int *loc_count,
+ int *mutex_count, int *thread_count,
+ int *unique_tid_count, void **sleep_trace,
+ unsigned long trace_size);
+int __tsan_get_report_tag(void *report, unsigned long *tag);
+}
+
+__attribute__((no_sanitize("thread"), noinline))
+void ExternalWrite(void *addr) {
+ void *kSwiftAccessRaceTag = (void *)0x1;
+ __tsan_external_write(addr, nullptr, kSwiftAccessRaceTag);
+}
+
+int main(int argc, char *argv[]) {
+ barrier_init(&barrier, 2);
+ fprintf(stderr, "Start.\n");
+ // CHECK: Start.
+
+ void *opaque_object = malloc(16);
+ std::thread t1([opaque_object] {
+ ExternalWrite(opaque_object);
+ barrier_wait(&barrier);
+ });
+ std::thread t2([opaque_object] {
+ barrier_wait(&barrier);
+ ExternalWrite(opaque_object);
+ });
+ // CHECK: WARNING: ThreadSanitizer: Swift access race
+ // CHECK: Modifying access of Swift variable at {{.*}} by thread {{.*}}
+ // CHECK: Previous modifying access of Swift variable at {{.*}} by thread {{.*}}
+ // CHECK: SUMMARY: ThreadSanitizer: Swift access race
+ t1.join();
+ t2.join();
+
+ fprintf(stderr, "Done.\n");
+}
+
+extern "C"
+void __tsan_on_report(void *report) {
+ const char *description;
+ int count;
+ int stack_count, mop_count, loc_count, mutex_count, thread_count,
+ unique_tid_count;
+ void *sleep_trace[16] = {0};
+ __tsan_get_report_data(report, &description, &count, &stack_count, &mop_count,
+ &loc_count, &mutex_count, &thread_count,
+ &unique_tid_count, sleep_trace, 16);
+ fprintf(stderr, "report type = '%s', count = %d\n", description, count);
+ // CHECK: report type = 'external-race', count = 0
+
+ unsigned long tag;
+ __tsan_get_report_tag(report, &tag);
+ fprintf(stderr, "tag = %ld\n", tag);
+ // CHECK: tag = 1
+}
+
+// CHECK: Done.
+// CHECK: ThreadSanitizer: reported 1 warnings
diff --git a/test/tsan/Darwin/gcd-after-null.mm b/test/tsan/Darwin/gcd-after-null.mm
deleted file mode 100644
index 7c9913c0fb17..000000000000
--- a/test/tsan/Darwin/gcd-after-null.mm
+++ /dev/null
@@ -1,23 +0,0 @@
-// Regression test to make sure we don't crash when dispatch_after is called with a NULL queue.
-
-// RUN: %clang_tsan %s -o %t -framework Foundation
-// RUN: %run %t 2>&1 | FileCheck %s
-
-#import <Foundation/Foundation.h>
-
-int main(int argc, const char *argv[]) {
- fprintf(stderr, "start\n");
-
- dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(10 * NSEC_PER_MSEC)), NULL, ^{
- dispatch_async(dispatch_get_main_queue(), ^{
- CFRunLoopStop(CFRunLoopGetMain());
- });
- });
- CFRunLoopRun();
-
- fprintf(stderr, "done\n");
- return 0;
-}
-
-// CHECK: start
-// CHECK: done
diff --git a/test/tsan/Darwin/norace-objcxx-run-time.mm b/test/tsan/Darwin/norace-objcxx-run-time.mm
index 1de431a076c7..ee76ec155cb4 100644
--- a/test/tsan/Darwin/norace-objcxx-run-time.mm
+++ b/test/tsan/Darwin/norace-objcxx-run-time.mm
@@ -1,4 +1,4 @@
-// RUN: %clang_tsan %s -lc++ -fobjc-arc -lobjc -o %t -framework Foundation
+// RUN: %clang_tsan %s -lc++ -fobjc-arc -lobjc -o %t -framework Foundation %darwin_min_target_with_full_runtime_arc_support
// RUN: %run %t 2>&1 | FileCheck %s
// Check that we do not report races between:
diff --git a/test/tsan/Darwin/objc-synchronize-tagged.mm b/test/tsan/Darwin/objc-synchronize-tagged.mm
new file mode 100644
index 000000000000..ab0af46ec4af
--- /dev/null
+++ b/test/tsan/Darwin/objc-synchronize-tagged.mm
@@ -0,0 +1,62 @@
+// RUN: %clangxx_tsan %s -o %t -framework Foundation -fobjc-arc %darwin_min_target_with_full_runtime_arc_support
+// RUN: %run %t 2>&1 | FileCheck %s
+
+#import <Foundation/Foundation.h>
+
+NSString *tagged_string = nil;
+
+@interface MyClass : NSObject {
+ long field;
+}
+@property(nonatomic, readonly) long value;
+@end
+
+dispatch_group_t group;
+
+@implementation MyClass
+
+- (void)start {
+ dispatch_queue_t q = dispatch_queue_create(NULL, NULL);
+ dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
+ for (int i = 0; i < 10; i++) {
+ dispatch_async(q, ^{
+ @synchronized(tagged_string) {
+ self->field = i;
+ }
+ });
+ }
+ });
+}
+
+- (long)value {
+ @synchronized(tagged_string) {
+ return self->field;
+ }
+}
+
+- (void)dealloc {
+ dispatch_group_leave(group);
+}
+
+@end
+
+int main() {
+ tagged_string = [NSString stringWithFormat:@"%s", "abc"];
+ uintptr_t tagged_string_bits = (uintptr_t)tagged_string;
+ assert((tagged_string_bits & 0x8000000000000001ull) != 0);
+ group = dispatch_group_create();
+ @autoreleasepool {
+ for (int j = 0; j < 100; ++j) {
+ dispatch_group_enter(group);
+ MyClass *obj = [[MyClass alloc] init];
+ [obj start];
+ long x = obj.value;
+ (void)x;
+ }
+ }
+ dispatch_group_wait(group, DISPATCH_TIME_FOREVER);
+ NSLog(@"Hello world");
+}
+
+// CHECK: Hello world
+// CHECK-NOT: WARNING: ThreadSanitizer
diff --git a/test/tsan/Darwin/objc-synchronize.mm b/test/tsan/Darwin/objc-synchronize.mm
new file mode 100644
index 000000000000..0bf06370a9b8
--- /dev/null
+++ b/test/tsan/Darwin/objc-synchronize.mm
@@ -0,0 +1,57 @@
+// RUN: %clangxx_tsan %s -o %t -framework Foundation -fobjc-arc %darwin_min_target_with_full_runtime_arc_support
+// RUN: %run %t 2>&1 | FileCheck %s
+
+#import <Foundation/Foundation.h>
+
+@interface MyClass : NSObject {
+ long field;
+}
+@property (nonatomic, readonly) long value;
+@end
+
+dispatch_group_t group;
+
+@implementation MyClass
+
+- (void) start {
+ dispatch_queue_t q = dispatch_queue_create(NULL, NULL);
+ dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
+ for (int i = 0; i < 1000; i++) {
+ dispatch_async(q, ^{
+ @synchronized(self) {
+ self->field = i;
+ }
+ });
+ }
+ });
+}
+
+- (long) value {
+ @synchronized(self) {
+ return self->field;
+ }
+}
+
+- (void)dealloc {
+ dispatch_group_leave(group);
+}
+
+@end
+
+int main() {
+ group = dispatch_group_create();
+ @autoreleasepool {
+ for (int j = 0; j < 100; ++j) {
+ dispatch_group_enter(group);
+ MyClass *obj = [[MyClass alloc] init];
+ [obj start];
+ long x = obj.value;
+ (void)x;
+ }
+ }
+ dispatch_group_wait(group, DISPATCH_TIME_FOREVER);
+ NSLog(@"Hello world");
+}
+
+// CHECK: Hello world
+// CHECK-NOT: WARNING: ThreadSanitizer
diff --git a/test/tsan/allocator_returns_null.cc b/test/tsan/allocator_returns_null.cc
deleted file mode 100644
index 5e2e2e9a53c7..000000000000
--- a/test/tsan/allocator_returns_null.cc
+++ /dev/null
@@ -1,124 +0,0 @@
-// Test the behavior of malloc/calloc/realloc/new when the allocation size is
-// more than TSan allocator's max allowed one.
-// By default (allocator_may_return_null=0) the process should crash.
-// With allocator_may_return_null=1 the allocator should return 0, except the
-// operator new(), which should crash anyway (operator new(std::nothrow) should
-// return nullptr, indeed).
-//
-// RUN: %clangxx_tsan -O0 %s -o %t
-// RUN: not %run %t malloc 2>&1 | FileCheck %s --check-prefix=CHECK-mCRASH
-// RUN: %env_tsan_opts=allocator_may_return_null=0 not %run %t malloc 2>&1 \
-// RUN: | FileCheck %s --check-prefix=CHECK-mCRASH
-// RUN: %env_tsan_opts=allocator_may_return_null=1 %run %t malloc 2>&1 \
-// RUN: | FileCheck %s --check-prefix=CHECK-mNULL
-// RUN: %env_tsan_opts=allocator_may_return_null=0 not %run %t calloc 2>&1 \
-// RUN: | FileCheck %s --check-prefix=CHECK-cCRASH
-// RUN: %env_tsan_opts=allocator_may_return_null=1 %run %t calloc 2>&1 \
-// RUN: | FileCheck %s --check-prefix=CHECK-cNULL
-// RUN: %env_tsan_opts=allocator_may_return_null=0 not %run %t calloc-overflow 2>&1 \
-// RUN: | FileCheck %s --check-prefix=CHECK-coCRASH
-// RUN: %env_tsan_opts=allocator_may_return_null=1 %run %t calloc-overflow 2>&1 \
-// RUN: | FileCheck %s --check-prefix=CHECK-coNULL
-// RUN: %env_tsan_opts=allocator_may_return_null=0 not %run %t realloc 2>&1 \
-// RUN: | FileCheck %s --check-prefix=CHECK-rCRASH
-// RUN: %env_tsan_opts=allocator_may_return_null=1 %run %t realloc 2>&1 \
-// RUN: | FileCheck %s --check-prefix=CHECK-rNULL
-// RUN: %env_tsan_opts=allocator_may_return_null=0 not %run %t realloc-after-malloc 2>&1 \
-// RUN: | FileCheck %s --check-prefix=CHECK-mrCRASH
-// RUN: %env_tsan_opts=allocator_may_return_null=1 %run %t realloc-after-malloc 2>&1 \
-// RUN: | FileCheck %s --check-prefix=CHECK-mrNULL
-// RUN: %env_tsan_opts=allocator_may_return_null=0 not %run %t new 2>&1 \
-// RUN: | FileCheck %s --check-prefix=CHECK-nCRASH
-// RUN: %env_tsan_opts=allocator_may_return_null=1 not %run %t new 2>&1 \
-// RUN: | FileCheck %s --check-prefix=CHECK-nCRASH
-// RUN: %env_tsan_opts=allocator_may_return_null=0 not %run %t new-nothrow 2>&1 \
-// RUN: | FileCheck %s --check-prefix=CHECK-nnCRASH
-// RUN: %env_tsan_opts=allocator_may_return_null=1 %run %t new-nothrow 2>&1 \
-// RUN: | FileCheck %s --check-prefix=CHECK-nnNULL
-
-#include <assert.h>
-#include <errno.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <limits>
-#include <new>
-
-int main(int argc, char **argv) {
- // Disable stderr buffering. Needed on Windows.
- setvbuf(stderr, NULL, _IONBF, 0);
-
- assert(argc == 2);
- const char *action = argv[1];
- fprintf(stderr, "%s:\n", action);
-
- // The limit enforced in tsan_mman.cc, user_alloc_internal function.
- static const size_t kMaxAllowedMallocSizePlusOne = (1ULL << 40) + 1;
-
- void *x = 0;
- if (!strcmp(action, "malloc")) {
- x = malloc(kMaxAllowedMallocSizePlusOne);
- } else if (!strcmp(action, "calloc")) {
- x = calloc((kMaxAllowedMallocSizePlusOne / 4) + 1, 4);
- } else if (!strcmp(action, "calloc-overflow")) {
- volatile size_t kMaxSizeT = std::numeric_limits<size_t>::max();
- size_t kArraySize = 4096;
- volatile size_t kArraySize2 = kMaxSizeT / kArraySize + 10;
- x = calloc(kArraySize, kArraySize2);
- } else if (!strcmp(action, "realloc")) {
- x = realloc(0, kMaxAllowedMallocSizePlusOne);
- } else if (!strcmp(action, "realloc-after-malloc")) {
- char *t = (char*)malloc(100);
- *t = 42;
- x = realloc(t, kMaxAllowedMallocSizePlusOne);
- assert(*t == 42);
- } else if (!strcmp(action, "new")) {
- x = operator new(kMaxAllowedMallocSizePlusOne);
- } else if (!strcmp(action, "new-nothrow")) {
- x = operator new(kMaxAllowedMallocSizePlusOne, std::nothrow);
- } else {
- assert(0);
- }
-
- fprintf(stderr, "errno: %d\n", errno);
-
- // The NULL pointer is printed differently on different systems, while (long)0
- // is always the same.
- fprintf(stderr, "x: %lx\n", (long)x);
- free(x);
-
- return x != 0;
-}
-
-// CHECK-mCRASH: malloc:
-// CHECK-mCRASH: ThreadSanitizer's allocator is terminating the process
-// CHECK-cCRASH: calloc:
-// CHECK-cCRASH: ThreadSanitizer's allocator is terminating the process
-// CHECK-coCRASH: calloc-overflow:
-// CHECK-coCRASH: ThreadSanitizer's allocator is terminating the process
-// CHECK-rCRASH: realloc:
-// CHECK-rCRASH: ThreadSanitizer's allocator is terminating the process
-// CHECK-mrCRASH: realloc-after-malloc:
-// CHECK-mrCRASH: ThreadSanitizer's allocator is terminating the process
-// CHECK-nCRASH: new:
-// CHECK-nCRASH: ThreadSanitizer's allocator is terminating the process
-// CHECK-nnCRASH: new-nothrow:
-// CHECK-nnCRASH: ThreadSanitizer's allocator is terminating the process
-
-// CHECK-mNULL: malloc:
-// CHECK-mNULL: errno: 12
-// CHECK-mNULL: x: 0
-// CHECK-cNULL: calloc:
-// CHECK-cNULL: errno: 12
-// CHECK-cNULL: x: 0
-// CHECK-coNULL: calloc-overflow:
-// CHECK-coNULL: errno: 12
-// CHECK-coNULL: x: 0
-// CHECK-rNULL: realloc:
-// CHECK-rNULL: errno: 12
-// CHECK-rNULL: x: 0
-// CHECK-mrNULL: realloc-after-malloc:
-// CHECK-mrNULL: errno: 12
-// CHECK-mrNULL: x: 0
-// CHECK-nnNULL: new-nothrow:
-// CHECK-nnNULL: x: 0
diff --git a/test/tsan/global_race.cc b/test/tsan/global_race.cc
index ec26b06f5c1c..01df3b6de9c3 100644
--- a/test/tsan/global_race.cc
+++ b/test/tsan/global_race.cc
@@ -1,12 +1,15 @@
-// RUN: %clangxx_tsan -O1 %s -o %T/global_race.cc.exe && %deflake %run %T/global_race.cc.exe 2>&1 \
+// RUN: rm -rf %t-dir
+// RUN: mkdir %t-dir
+
+// RUN: %clangxx_tsan -O1 %s -o %t-dir/global_race.cc.exe && %deflake %run %t-dir/global_race.cc.exe 2>&1 \
// RUN: | FileCheck %s
// Also check that memory access instrumentation can be configured by either
// driver or legacy flags:
-// RUN: %clangxx_tsan -O1 %s -o %T/global_race.cc.exe -fno-sanitize-thread-memory-access && not %deflake %run %T/global_race.cc.exe 2>&1 \
+// RUN: %clangxx_tsan -O1 %s -o %t-dir/global_race.cc.exe -fno-sanitize-thread-memory-access && not %deflake %run %t-dir/global_race.cc.exe 2>&1 \
// RUN: | FileCheck --allow-empty --check-prefix=CHECK-MEMORY-ACCESS-OFF %s
-// RUN: %clangxx_tsan -O1 %s -o %T/global_race.cc.exe -mllvm -tsan-instrument-memory-accesses=0 && not %deflake %run %T/global_race.cc.exe 2>&1 \
+// RUN: %clangxx_tsan -O1 %s -o %t-dir/global_race.cc.exe -mllvm -tsan-instrument-memory-accesses=0 && not %deflake %run %t-dir/global_race.cc.exe 2>&1 \
// RUN: | FileCheck --allow-empty --check-prefix=CHECK-MEMORY-ACCESS-OFF %s
#include "test.h"
diff --git a/test/tsan/ignore_lib0.cc b/test/tsan/ignore_lib0.cc
index 84632019fccb..2b217f21ff56 100644
--- a/test/tsan/ignore_lib0.cc
+++ b/test/tsan/ignore_lib0.cc
@@ -1,9 +1,12 @@
-// RUN: %clangxx_tsan -O1 %s -DLIB -fPIC -fno-sanitize=thread -shared -o %T/libignore_lib0.so
-// RUN: %clangxx_tsan -O1 %s -L%T -lignore_lib0 -o %t
+// RUN: rm -rf %t-dir
+// RUN: mkdir %t-dir
+
+// RUN: %clangxx_tsan -O1 %s -DLIB -fPIC -fno-sanitize=thread -shared -o %t-dir/libignore_lib0.so
+// RUN: %clangxx_tsan -O1 %s -L%t-dir -lignore_lib0 -o %t
// RUN: echo running w/o suppressions:
-// RUN: env LD_LIBRARY_PATH=%T${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH} %deflake %run %t | FileCheck %s --check-prefix=CHECK-NOSUPP
+// RUN: env LD_LIBRARY_PATH=%t-dir${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH} %deflake %run %t | FileCheck %s --check-prefix=CHECK-NOSUPP
// RUN: echo running with suppressions:
-// RUN: env LD_LIBRARY_PATH=%T${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH} %env_tsan_opts=suppressions='%s.supp' %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-WITHSUPP
+// RUN: env LD_LIBRARY_PATH=%t-dir${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH} %env_tsan_opts=suppressions='%s.supp' %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-WITHSUPP
// Tests that interceptors coming from a library specified in called_from_lib
// suppression are ignored.
diff --git a/test/tsan/ignore_lib1.cc b/test/tsan/ignore_lib1.cc
index 5949d811ed44..1660cf3e41f9 100644
--- a/test/tsan/ignore_lib1.cc
+++ b/test/tsan/ignore_lib1.cc
@@ -1,9 +1,12 @@
-// RUN: %clangxx_tsan -O1 %s -DLIB -fPIC -fno-sanitize=thread -shared -o %T/libignore_lib1.so
-// RUN: %clangxx_tsan -O1 %s -o %t
+// RUN: rm -rf %t-dir
+// RUN: mkdir %t-dir
+
+// RUN: %clangxx_tsan -O1 %s -DLIB -fPIC -fno-sanitize=thread -shared -o %t-dir/libignore_lib1.so
+// RUN: %clangxx_tsan -O1 %s -o %t-dir/executable
// RUN: echo running w/o suppressions:
-// RUN: %deflake %run %t | FileCheck %s --check-prefix=CHECK-NOSUPP
+// RUN: %deflake %run %t-dir/executable | FileCheck %s --check-prefix=CHECK-NOSUPP
// RUN: echo running with suppressions:
-// RUN: %env_tsan_opts=suppressions='%s.supp' %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-WITHSUPP
+// RUN: %env_tsan_opts=suppressions='%s.supp' %run %t-dir/executable 2>&1 | FileCheck %s --check-prefix=CHECK-WITHSUPP
// Tests that interceptors coming from a dynamically loaded library specified
// in called_from_lib suppression are ignored.
diff --git a/test/tsan/ignore_lib2.cc b/test/tsan/ignore_lib2.cc
index 4f584b14664a..e0dac5670122 100644
--- a/test/tsan/ignore_lib2.cc
+++ b/test/tsan/ignore_lib2.cc
@@ -1,7 +1,10 @@
-// RUN: %clangxx_tsan -O1 %s -DLIB -fPIC -fno-sanitize=thread -shared -o %T/libignore_lib2_0.so
-// RUN: %clangxx_tsan -O1 %s -DLIB -fPIC -fno-sanitize=thread -shared -o %T/libignore_lib2_1.so
-// RUN: %clangxx_tsan -O1 %s -o %t
-// RUN: %env_tsan_opts=suppressions='%s.supp' %deflake %run %t | FileCheck %s
+// RUN: rm -rf %t-dir
+// RUN: mkdir %t-dir
+
+// RUN: %clangxx_tsan -O1 %s -DLIB -fPIC -fno-sanitize=thread -shared -o %t-dir/libignore_lib2_0.so
+// RUN: %clangxx_tsan -O1 %s -DLIB -fPIC -fno-sanitize=thread -shared -o %t-dir/libignore_lib2_1.so
+// RUN: %clangxx_tsan -O1 %s -o %t-dir/executable
+// RUN: %env_tsan_opts=suppressions='%s.supp' %deflake %run %t-dir/executable | FileCheck %s
// Tests that called_from_lib suppression matched against 2 libraries
// causes program crash (this is not supported).
diff --git a/test/tsan/ignore_lib3.cc b/test/tsan/ignore_lib3.cc
index 3f7be5cf8233..a5af07fdd112 100644
--- a/test/tsan/ignore_lib3.cc
+++ b/test/tsan/ignore_lib3.cc
@@ -1,6 +1,9 @@
-// RUN: %clangxx_tsan -O1 %s -DLIB -fPIC -fno-sanitize=thread -shared -o %T/libignore_lib3.so
-// RUN: %clangxx_tsan -O1 %s -o %t
-// RUN: %env_tsan_opts=suppressions='%s.supp' %deflake %run %t | FileCheck %s
+// RUN: rm -rf %t-dir
+// RUN: mkdir %t-dir
+
+// RUN: %clangxx_tsan -O1 %s -DLIB -fPIC -fno-sanitize=thread -shared -o %t-dir/libignore_lib3.so
+// RUN: %clangxx_tsan -O1 %s -o %t-dir/executable
+// RUN: %env_tsan_opts=suppressions='%s.supp' %deflake %run %t-dir/executable | FileCheck %s
// Tests that unloading of a library matched against called_from_lib suppression
// causes program crash (this is not supported).
diff --git a/test/tsan/ignore_lib4.cc b/test/tsan/ignore_lib4.cc
index 84d8b2768a94..da636ae3bf37 100644
--- a/test/tsan/ignore_lib4.cc
+++ b/test/tsan/ignore_lib4.cc
@@ -1,7 +1,10 @@
-// RUN: %clangxx_tsan -O1 %s -DLIB -fPIC -shared -o %T/libignore_lib4.so
-// RUN: %clangxx_tsan -O1 %s -o %t
-// RUN: echo "called_from_lib:libignore_lib4.so" > %t.supp
-// RUN: %env_tsan_opts=suppressions='%t.supp' %run %t 2>&1 | FileCheck %s
+// RUN: rm -rf %t-dir
+// RUN: mkdir %t-dir
+
+// RUN: %clangxx_tsan -O1 %s -DLIB -fPIC -shared -o %t-dir/libignore_lib4.so
+// RUN: %clangxx_tsan -O1 %s -o %t-dir/executable
+// RUN: echo "called_from_lib:libignore_lib4.so" > %t-dir/executable.supp
+// RUN: %env_tsan_opts=suppressions='%t-dir/executable.supp' %run %t-dir/executable 2>&1 | FileCheck %s
// powerpc64 big endian bots failed with "FileCheck error: '-' is empty" due
// to a segmentation fault.
diff --git a/test/tsan/ignore_lib5.cc b/test/tsan/ignore_lib5.cc
index 54630d534c34..d6c3f870e49b 100644
--- a/test/tsan/ignore_lib5.cc
+++ b/test/tsan/ignore_lib5.cc
@@ -1,9 +1,12 @@
-// RUN: %clangxx_tsan -O1 %s -DLIB -fPIC -fno-sanitize=thread -shared -o %T/libignore_lib1.so
-// RUN: %clangxx_tsan -O1 %s -o %t
+// RUN: rm -rf %t-dir
+// RUN: mkdir %t-dir
+
+// RUN: %clangxx_tsan -O1 %s -DLIB -fPIC -fno-sanitize=thread -shared -o %t-dir/libignore_lib1.so
+// RUN: %clangxx_tsan -O1 %s -o %t-dir/executable
// RUN: echo running w/o suppressions:
-// RUN: %deflake %run %t | FileCheck %s --check-prefix=CHECK-NOSUPP
+// RUN: %deflake %run %t-dir/executable | FileCheck %s --check-prefix=CHECK-NOSUPP
// RUN: echo running with suppressions:
-// RUN: %env_tsan_opts=suppressions='%s.supp' %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-WITHSUPP
+// RUN: %env_tsan_opts=suppressions='%s.supp' %run %t-dir/executable 2>&1 | FileCheck %s --check-prefix=CHECK-WITHSUPP
// REQUIRES: stable-runtime
// UNSUPPORTED: powerpc64le
diff --git a/test/tsan/ignored-interceptors-mmap.cc b/test/tsan/ignored-interceptors-mmap.cc
index 8715883238e2..796ea9323345 100644
--- a/test/tsan/ignored-interceptors-mmap.cc
+++ b/test/tsan/ignored-interceptors-mmap.cc
@@ -1,6 +1,7 @@
// RUN: %clangxx_tsan -O0 %s -o %t
// RUN: not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-NORMAL
// RUN: %env_tsan_opts=ignore_interceptors_accesses=1 %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-IGNORE
+// XFAIL: freebsd
#include <errno.h>
#include <sys/mman.h>
diff --git a/test/tsan/java_symbolization.cc b/test/tsan/java_symbolization.cc
index aa5ec0c37558..f82bd5ead48e 100644
--- a/test/tsan/java_symbolization.cc
+++ b/test/tsan/java_symbolization.cc
@@ -2,18 +2,13 @@
#include "java.h"
#include <memory.h>
-extern "C" bool __tsan_symbolize_external(jptr pc,
- char *func_buf, jptr func_siz,
- char *file_buf, jptr file_siz,
- int *line, int *col) {
+extern "C" void __tsan_symbolize_external_ex(
+ jptr pc, void (*add_frame)(void *, const char *, const char *, int, int),
+ void *ctx) {
if (pc == (1234 | kExternalPCBit)) {
- memcpy(func_buf, "MyFunc", sizeof("MyFunc"));
- memcpy(file_buf, "MyFile.java", sizeof("MyFile.java"));
- *line = 1234;
- *col = 56;
- return true;
+ add_frame(ctx, "MyInnerFunc", "MyInnerFile.java", 1234, 56);
+ add_frame(ctx, "MyOuterFunc", "MyOuterFile.java", 4321, 65);
}
- return false;
}
void *Thread(void *p) {
@@ -40,5 +35,6 @@ int main() {
}
// CHECK: WARNING: ThreadSanitizer: data race
-// CHECK: #0 MyFunc MyFile.java:1234:56
+// CHECK: #0 MyInnerFunc MyInnerFile.java:1234:56
+// CHECK: #1 MyOuterFunc MyOuterFile.java:4321:65
// CHECK: DONE
diff --git a/test/tsan/java_symbolization_legacy.cc b/test/tsan/java_symbolization_legacy.cc
new file mode 100644
index 000000000000..aa5ec0c37558
--- /dev/null
+++ b/test/tsan/java_symbolization_legacy.cc
@@ -0,0 +1,44 @@
+// RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
+#include "java.h"
+#include <memory.h>
+
+extern "C" bool __tsan_symbolize_external(jptr pc,
+ char *func_buf, jptr func_siz,
+ char *file_buf, jptr file_siz,
+ int *line, int *col) {
+ if (pc == (1234 | kExternalPCBit)) {
+ memcpy(func_buf, "MyFunc", sizeof("MyFunc"));
+ memcpy(file_buf, "MyFile.java", sizeof("MyFile.java"));
+ *line = 1234;
+ *col = 56;
+ return true;
+ }
+ return false;
+}
+
+void *Thread(void *p) {
+ barrier_wait(&barrier);
+ __tsan_write1_pc((jptr)p, 1234 | kExternalPCBit);
+ return 0;
+}
+
+int main() {
+ barrier_init(&barrier, 2);
+ int const kHeapSize = 1024 * 1024;
+ jptr jheap = (jptr)malloc(kHeapSize + 8) + 8;
+ __tsan_java_init(jheap, kHeapSize);
+ const int kBlockSize = 16;
+ __tsan_java_alloc(jheap, kBlockSize);
+ pthread_t th;
+ pthread_create(&th, 0, Thread, (void*)jheap);
+ __tsan_write1_pc((jptr)jheap, 1234 | kExternalPCBit);
+ barrier_wait(&barrier);
+ pthread_join(th, 0);
+ __tsan_java_free(jheap, kBlockSize);
+ fprintf(stderr, "DONE\n");
+ return __tsan_java_fini();
+}
+
+// CHECK: WARNING: ThreadSanitizer: data race
+// CHECK: #0 MyFunc MyFile.java:1234:56
+// CHECK: DONE
diff --git a/test/tsan/lit.cfg b/test/tsan/lit.cfg
index fdbafefbc66f..233d273f3130 100644
--- a/test/tsan/lit.cfg
+++ b/test/tsan/lit.cfg
@@ -56,7 +56,7 @@ clang_tsan_cxxflags = config.cxx_mode_flags + clang_tsan_cflags + ["-std=c++11"]
if config.has_libcxx and config.host_os != 'Darwin':
# FIXME: Dehardcode this path somehow.
libcxx_path = os.path.join(config.compiler_rt_obj_root, "lib",
- "tsan", "libcxx_tsan_" + config.target_arch)
+ "tsan", "libcxx_tsan_%s" % config.target_arch)
libcxx_incdir = os.path.join(libcxx_path, "include", "c++", "v1")
libcxx_libdir = os.path.join(libcxx_path, "lib")
libcxx_so = os.path.join(libcxx_libdir, "libc++.so")
@@ -85,5 +85,8 @@ if config.host_os not in ['FreeBSD', 'Linux', 'Darwin', 'NetBSD']:
if config.android:
config.unsupported = True
-if config.host_os == 'Darwin' and config.target_arch in ["x86_64", "x86_64h"]:
- config.parallelism_group = "darwin-64bit-sanitizer"
+if config.host_os == 'Darwin':
+ if config.target_arch in ["x86_64", "x86_64h"]:
+ config.parallelism_group = "darwin-64bit-sanitizer"
+ elif config.apple_platform != "osx" and not config.apple_platform.endswith("sim"):
+ config.parallelism_group = "darwin-ios-device-sanitizer"
diff --git a/test/tsan/lit.site.cfg.in b/test/tsan/lit.site.cfg.in
index a215e664a5b4..6dec5f92b271 100644
--- a/test/tsan/lit.site.cfg.in
+++ b/test/tsan/lit.site.cfg.in
@@ -3,8 +3,7 @@
config.name_suffix = "@TSAN_TEST_CONFIG_SUFFIX@"
config.tsan_lit_source_dir = "@TSAN_LIT_SOURCE_DIR@"
config.has_libcxx = @TSAN_HAS_LIBCXX@
-config.ios = @TSAN_TEST_IOS_PYBOOL@
-config.iossim = @TSAN_TEST_IOSSIM_PYBOOL@
+config.apple_platform = "@TSAN_TEST_APPLE_PLATFORM@"
config.target_cflags = "@TSAN_TEST_TARGET_CFLAGS@"
config.target_arch = "@TSAN_TEST_TARGET_ARCH@"
diff --git a/test/tsan/mutex_destroy_locked2.cc b/test/tsan/mutex_destroy_locked2.cc
new file mode 100644
index 000000000000..e29c96138a8e
--- /dev/null
+++ b/test/tsan/mutex_destroy_locked2.cc
@@ -0,0 +1,29 @@
+// RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
+#include <pthread.h>
+#include <unistd.h>
+
+void *thread(void *arg) {
+ pthread_mutex_t m;
+ pthread_mutex_init(&m, 0);
+ pthread_mutex_lock(&m);
+ pthread_mutex_destroy(&m);
+ return 0;
+}
+
+int main() {
+ pthread_t th;
+ pthread_create(&th, 0, thread, 0);
+ pthread_join(th, 0);
+ return 0;
+}
+
+// CHECK: WARNING: ThreadSanitizer: destroy of a locked mutex
+// CHECK: #0 pthread_mutex_destroy
+// CHECK: #1 thread
+// CHECK: and:
+// CHECK: #0 pthread_mutex_lock
+// CHECK: #1 thread
+// CHECK: Mutex {{.*}} created at:
+// CHECK: #0 pthread_mutex_init
+// CHECK: #1 thread
+// CHECK: SUMMARY: ThreadSanitizer: destroy of a locked mutex {{.*}} in thread
diff --git a/test/tsan/race_on_fputs.cc b/test/tsan/race_on_fputs.cc
new file mode 100644
index 000000000000..53042e3d36bc
--- /dev/null
+++ b/test/tsan/race_on_fputs.cc
@@ -0,0 +1,29 @@
+// RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
+#include "test.h"
+
+char s[] = "abracadabra";
+
+void *Thread0(void *p) {
+ fputs(s, stdout);
+ barrier_wait(&barrier);
+ return 0;
+}
+
+void *Thread1(void *p) {
+ barrier_wait(&barrier);
+ s[3] = 'z';
+ return 0;
+}
+
+int main() {
+ barrier_init(&barrier, 2);
+ pthread_t th[2];
+ pthread_create(&th[0], 0, Thread0, 0);
+ pthread_create(&th[1], 0, Thread1, 0);
+ pthread_join(th[0], 0);
+ pthread_join(th[1], 0);
+ fprintf(stderr, "DONE");
+}
+
+// CHECK: WARNING: ThreadSanitizer: data race
+// CHECK: DONE
diff --git a/test/tsan/simple_stack2.cc b/test/tsan/simple_stack2.cc
index 12ee0da31090..bbea71307749 100644
--- a/test/tsan/simple_stack2.cc
+++ b/test/tsan/simple_stack2.cc
@@ -1,4 +1,4 @@
-// RUN: %clangxx_tsan -O1 %s -o %T/simple_stack2.cc.exe && %deflake %run %T/simple_stack2.cc.exe | FileCheck %s
+// RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
#include "test.h"
int Global;
@@ -44,10 +44,10 @@ int main() {
// CHECK: WARNING: ThreadSanitizer: data race
// CHECK-NEXT: Write of size 4 at {{.*}} by thread T1:
-// CHECK-NEXT: #0 foo1{{.*}} {{.*}}simple_stack2.cc:7{{(:10)?}} ({{.*}})
-// CHECK-NEXT: #1 bar1{{.*}} {{.*}}simple_stack2.cc:14{{(:3)?}} ({{.*}})
-// CHECK-NEXT: #2 Thread1{{.*}} {{.*}}simple_stack2.cc:32{{(:3)?}} ({{.*}})
+// CHECK-NEXT: #0 foo1{{.*}} {{.*}}simple_stack2.cc:[[@LINE-40]]{{(:10)?}} ({{.*}})
+// CHECK-NEXT: #1 bar1{{.*}} {{.*}}simple_stack2.cc:[[@LINE-34]]{{(:3)?}} ({{.*}})
+// CHECK-NEXT: #2 Thread1{{.*}} {{.*}}simple_stack2.cc:[[@LINE-17]]{{(:3)?}} ({{.*}})
// CHECK: Previous read of size 4 at {{.*}} by main thread:
-// CHECK-NEXT: #0 foo2{{.*}} {{.*}}simple_stack2.cc:18{{(:22)?}} ({{.*}})
-// CHECK-NEXT: #1 bar2{{.*}} {{.*}}simple_stack2.cc:27{{(:3)?}} ({{.*}})
-// CHECK-NEXT: #2 main{{.*}} {{.*}}simple_stack2.cc:40{{(:3)?}} ({{.*}})
+// CHECK-NEXT: #0 foo2{{.*}} {{.*}}simple_stack2.cc:[[@LINE-33]]{{(:22)?}} ({{.*}})
+// CHECK-NEXT: #1 bar2{{.*}} {{.*}}simple_stack2.cc:[[@LINE-25]]{{(:3)?}} ({{.*}})
+// CHECK-NEXT: #2 main{{.*}} {{.*}}simple_stack2.cc:[[@LINE-13]]{{(:3)?}} ({{.*}})
diff --git a/test/tsan/static_init6.cc b/test/tsan/static_init6.cc
index fd22e0a02e6a..06215ced3c76 100644
--- a/test/tsan/static_init6.cc
+++ b/test/tsan/static_init6.cc
@@ -1,4 +1,5 @@
-// RUN: %clangxx_tsan -stdlib=libstdc++ -static-libstdc++ -O1 %s -o %t && %run %t 2>&1 | FileCheck %s
+// RUN: %clangxx_tsan %linux_static_libstdcplusplus -O1 %s -o %t && %run %t 2>&1 \
+// RUN: | FileCheck %s
#include <pthread.h>
#include <stdlib.h>
#include <stdio.h>
diff --git a/test/tsan/strerror_r.cc b/test/tsan/strerror_r.cc
index ad482013012c..cfe8a18c1736 100644
--- a/test/tsan/strerror_r.cc
+++ b/test/tsan/strerror_r.cc
@@ -1,26 +1,30 @@
// RUN: %clangxx_tsan -O1 -DTEST_ERROR=ERANGE %s -o %t && %run %t 2>&1 | FileCheck --check-prefixes=CHECK,CHECK-SYS %s
// RUN: %clangxx_tsan -O1 -DTEST_ERROR=-1 %s -o %t && not %run %t 2>&1 | FileCheck --check-prefixes=CHECK,CHECK-USER %s
// UNSUPPORTED: darwin
+// This test provokes a data race under FreeBSD
+// XFAIL: freebsd
+
+#include "test.h"
-#include <assert.h>
#include <errno.h>
#include <pthread.h>
-#include <stdio.h>
#include <string.h>
char buffer[1000];
void *Thread(void *p) {
+ barrier_wait(&barrier);
strerror_r(TEST_ERROR, buffer, sizeof(buffer));
return buffer;
}
int main() {
- pthread_t th[2];
- pthread_create(&th[0], 0, Thread, 0);
- pthread_create(&th[1], 0, Thread, 0);
- pthread_join(th[0], 0);
- pthread_join(th[1], 0);
+ barrier_init(&barrier, 2);
+ pthread_t th;
+ pthread_create(&th, 0, Thread, 0);
+ strerror_r(TEST_ERROR, buffer, sizeof(buffer));
+ barrier_wait(&barrier);
+ pthread_join(th, 0);
fprintf(stderr, "DONE\n");
}
diff --git a/test/tsan/suppressions_mutex.cc b/test/tsan/suppressions_mutex.cc
new file mode 100644
index 000000000000..5d3a5d05289f
--- /dev/null
+++ b/test/tsan/suppressions_mutex.cc
@@ -0,0 +1,19 @@
+// RUN: %clang_tsan -O1 %s -o %t && %env_tsan_opts=suppressions='%s.supp' %run %t 2>&1 | FileCheck %s
+#include "test.h"
+
+void __attribute__((noinline)) suppress_this(pthread_mutex_t *mu) {
+ pthread_mutex_destroy(mu);
+}
+
+int main() {
+ pthread_mutex_t mu;
+ pthread_mutex_init(&mu, 0);
+ pthread_mutex_lock(&mu);
+ suppress_this(&mu);
+ fprintf(stderr, "DONE\n");
+ return 0;
+}
+
+// CHECK-NOT: failed to open suppressions file
+// CHECK-NOT: WARNING: ThreadSanitizer:
+// CHECK: DONE
diff --git a/test/tsan/suppressions_mutex.cc.supp b/test/tsan/suppressions_mutex.cc.supp
new file mode 100644
index 000000000000..595febbea5ce
--- /dev/null
+++ b/test/tsan/suppressions_mutex.cc.supp
@@ -0,0 +1,2 @@
+mutex:suppress_this
+
diff --git a/test/tsan/test.h b/test/tsan/test.h
index bc4f7aad55fe..595590b58ce2 100644
--- a/test/tsan/test.h
+++ b/test/tsan/test.h
@@ -56,7 +56,7 @@ unsigned long long monotonic_clock_ns() {
#endif
//The const kPCInc must be in sync with StackTrace::GetPreviousInstructionPc
-#if defined(__powerpc64__)
+#if defined(__powerpc64__) || defined(__arm__) || defined(__aarch64__)
// PCs are always 4 byte aligned.
const int kPCInc = 4;
#elif defined(__sparc__) || defined(__mips__)
diff --git a/test/tsan/thread_name.cc b/test/tsan/thread_name.cc
index 17caa62ef440..1fa055579ee0 100644
--- a/test/tsan/thread_name.cc
+++ b/test/tsan/thread_name.cc
@@ -7,7 +7,7 @@
#elif defined(__FreeBSD__)
#include <pthread_np.h>
#define USE_PTHREAD_SETNAME_NP 1
-#define tasn_pthread_setname_np pthread_set_name_np
+#define tsan_pthread_setname_np pthread_set_name_np
#elif defined(__NetBSD__)
#define USE_PTHREAD_SETNAME_NP 1
#define tsan_pthread_setname_np(a, b) pthread_setname_np((a), "%s", (void *)(b))
diff --git a/test/tsan/tls_race2.cc b/test/tsan/tls_race2.cc
index f3139b69fc08..5968e66d5b18 100644
--- a/test/tsan/tls_race2.cc
+++ b/test/tsan/tls_race2.cc
@@ -22,6 +22,8 @@ int main() {
pthread_t t;
pthread_create(&t, 0, Thread, 0);
pthread_join(t, 0);
+ fprintf(stderr, "DONE\n");
+ return 0;
}
// CHECK: WARNING: ThreadSanitizer: data race
@@ -29,3 +31,4 @@ int main() {
// CHECK-FreeBSD: Location is TLS of thread T1.
// CHECK-NetBSD: Location is TLS of thread T1.
// CHECK-Darwin: Location is heap block of size 4
+// CHECK: DONE
diff --git a/test/ubsan/CMakeLists.txt b/test/ubsan/CMakeLists.txt
index 7791681472fd..fa8b16b8093e 100644
--- a/test/ubsan/CMakeLists.txt
+++ b/test/ubsan/CMakeLists.txt
@@ -38,6 +38,9 @@ set(UBSAN_TEST_ARCH ${UBSAN_SUPPORTED_ARCH})
if(APPLE)
darwin_filter_host_archs(UBSAN_SUPPORTED_ARCH UBSAN_TEST_ARCH)
endif()
+if(OS_NAME MATCHES "SunOS")
+ list(REMOVE_ITEM UBSAN_TEST_ARCH x86_64)
+endif()
foreach(arch ${UBSAN_TEST_ARCH})
set(UBSAN_TEST_TARGET_ARCH ${arch})
diff --git a/test/ubsan/TestCases/Float/cast-overflow.cpp b/test/ubsan/TestCases/Float/cast-overflow.cpp
index a53c663b1367..460150aa3b2e 100644
--- a/test/ubsan/TestCases/Float/cast-overflow.cpp
+++ b/test/ubsan/TestCases/Float/cast-overflow.cpp
@@ -29,6 +29,16 @@
# ifndef LITTLE_ENDIAN
# define LITTLE_ENDIAN _LITTLE_ENDIAN
# endif
+#elif defined(__sun__) && defined(__svr4__)
+// Solaris provides _BIG_ENDIAN/_LITTLE_ENDIAN selector in sys/types.h.
+# include <sys/types.h>
+# define BIG_ENDIAN 4321
+# define LITTLE_ENDIAN 1234
+# if defined(_BIG_ENDIAN)
+# define BYTE_ORDER BIG_ENDIAN
+# else
+# define BYTE_ORDER LITTLE_ENDIAN
+# endif
#elif defined(_WIN32)
# define BYTE_ORDER 0
# define BIG_ENDIAN 1
diff --git a/test/ubsan/TestCases/Integer/negate-overflow.cpp b/test/ubsan/TestCases/Integer/negate-overflow.cpp
index 72438d3fba7f..5e36b9db657f 100644
--- a/test/ubsan/TestCases/Integer/negate-overflow.cpp
+++ b/test/ubsan/TestCases/Integer/negate-overflow.cpp
@@ -1,10 +1,12 @@
// RUN: %clangxx -fsanitize=signed-integer-overflow %s -o %t1 && %run %t1 2>&1 | FileCheck %s --check-prefix=CHECKS
// RUN: %clangxx -fsanitize=unsigned-integer-overflow %s -o %t2 && %run %t2 2>&1 | FileCheck %s --check-prefix=CHECKU
+// RUN: %clangxx -fsanitize=unsigned-integer-overflow %s -o %t2 && %env_ubsan_opts=silence_unsigned_overflow=1 %run %t2 2>&1 | FileCheck %s --check-prefix=CHECKU-SILENT --allow-empty
int main() {
// CHECKS-NOT: runtime error
- // CHECKU: negate-overflow.cpp:[[@LINE+2]]:3: runtime error: negation of 2147483648 cannot be represented in type 'unsigned int'
+ // CHECKU: negate-overflow.cpp:[[@LINE+3]]:3: runtime error: negation of 2147483648 cannot be represented in type 'unsigned int'
// CHECKU-NOT: cast to an unsigned
+ // CHECKU-SILENT-NOT: runtime error
-unsigned(-0x7fffffff - 1); // ok
// CHECKS: negate-overflow.cpp:[[@LINE+2]]:3: runtime error: negation of -2147483648 cannot be represented in type 'int'; cast to an unsigned type to negate this value to itself
// CHECKU-NOT: runtime error
diff --git a/test/ubsan/TestCases/Integer/no-recover.cpp b/test/ubsan/TestCases/Integer/no-recover.cpp
index bbc2f8d2c1c4..515ebbd0702e 100644
--- a/test/ubsan/TestCases/Integer/no-recover.cpp
+++ b/test/ubsan/TestCases/Integer/no-recover.cpp
@@ -1,5 +1,6 @@
// RUN: %clangxx -fsanitize=unsigned-integer-overflow %s -o %t && %run %t 2>&1 | FileCheck %s --check-prefix=RECOVER
// RUN: %clangxx -fsanitize=unsigned-integer-overflow -fno-sanitize-recover=all -fsanitize-recover=unsigned-integer-overflow %s -o %t && %run %t 2>&1 | FileCheck %s --check-prefix=RECOVER
+// RUN: %env_ubsan_opts=silence_unsigned_overflow=1 %run %t 2>&1 | FileCheck %s --check-prefix=SILENT-RECOVER --allow-empty
// RUN: %clangxx -fsanitize=unsigned-integer-overflow -fno-sanitize-recover=unsigned-integer-overflow %s -o %t && not %run %t 2>&1 | FileCheck %s --check-prefix=ABORT
#include <stdint.h>
@@ -18,5 +19,6 @@ int main() {
(void)(uint64_t(10000000000000000000ull) + uint64_t(9000000000000000000ull));
// RECOVER: 10000000000000000000 + 9000000000000000000 cannot be represented in type 'unsigned {{long( long)?}}'
+ // SILENT-RECOVER-NOT: runtime error
// ABORT-NOT: runtime error
}
diff --git a/test/ubsan/TestCases/Integer/suppressions.cpp b/test/ubsan/TestCases/Integer/suppressions.cpp
index f72d82edf278..65d8bba13b01 100644
--- a/test/ubsan/TestCases/Integer/suppressions.cpp
+++ b/test/ubsan/TestCases/Integer/suppressions.cpp
@@ -4,6 +4,8 @@
// requires the compiler-rt runtime to be able to symbolize stack addresses.
// REQUIRES: can-symbolize
// UNSUPPORTED: android
+// Output differs on OpenBSD longer by displaying the values.
+// XFAIL: openbsd
// Fails without any suppression.
// RUN: %env_ubsan_opts=halt_on_error=1 not %run %t 2>&1 | FileCheck %s
diff --git a/test/ubsan/TestCases/Misc/coverage-levels.cc b/test/ubsan/TestCases/Misc/coverage-levels.cc
index 05c19937ddf8..364f985c5051 100644
--- a/test/ubsan/TestCases/Misc/coverage-levels.cc
+++ b/test/ubsan/TestCases/Misc/coverage-levels.cc
@@ -3,26 +3,28 @@
// FIXME: Port the environment variable logic below for the lit shell.
// REQUIRES: shell
//
-// RUN: rm -rf %T/coverage-levels && mkdir %T/coverage-levels
+// RUN: rm -rf %t-dir && mkdir %t-dir
// RUN: %clangxx -fsanitize=shift -DGOOD_SHIFT=1 -O1 -fsanitize-coverage=func %s -o %t
-// RUN: %env_ubsan_opts=coverage=1:verbosity=1:coverage_dir='"%T/coverage-levels"' %run %t 2>&1 | FileCheck %s --check-prefix=CHECK1 --check-prefix=CHECK_NOWARN
+// RUN: %env_ubsan_opts=coverage=1:verbosity=1:coverage_dir='"%t-dir"' %run %t 2>&1 | FileCheck %s --check-prefix=CHECK1 --check-prefix=CHECK_NOWARN
// RUN: %clangxx -fsanitize=undefined -DGOOD_SHIFT=1 -O1 -fsanitize-coverage=func %s -o %t
-// RUN: %env_ubsan_opts=coverage=1:verbosity=1:coverage_dir='"%T/coverage-levels"' %run %t 2>&1 | FileCheck %s --check-prefix=CHECK1 --check-prefix=CHECK_NOWARN
+// RUN: %env_ubsan_opts=coverage=1:verbosity=1:coverage_dir='"%t-dir"' %run %t 2>&1 | FileCheck %s --check-prefix=CHECK1 --check-prefix=CHECK_NOWARN
// Also works without any sanitizer.
// RUN: %clangxx -DGOOD_SHIFT=1 -O1 -fsanitize-coverage=func %s -o %t
-// RUN: %env_ubsan_opts=coverage=1:verbosity=1:coverage_dir='"%T/coverage-levels"' %run %t 2>&1 | FileCheck %s --check-prefix=CHECK1 --check-prefix=CHECK_NOWARN
+// RUN: %env_ubsan_opts=coverage=1:verbosity=1:coverage_dir='"%t-dir"' %run %t 2>&1 | FileCheck %s --check-prefix=CHECK1 --check-prefix=CHECK_NOWARN
// RUN: %clangxx -fsanitize=shift -O1 -fsanitize-coverage=func %s -o %t
-// RUN: %env_ubsan_opts=coverage=1:verbosity=1:coverage_dir='"%T/coverage-levels"' %run %t 2>&1 | FileCheck %s --check-prefix=CHECK1 --check-prefix=CHECK_WARN
+// RUN: %env_ubsan_opts=coverage=1:verbosity=1:coverage_dir='"%t-dir"' %run %t 2>&1 | FileCheck %s --check-prefix=CHECK1 --check-prefix=CHECK_WARN
// RUN: %clangxx -fsanitize=shift -O1 -fsanitize-coverage=bb %s -o %t
-// RUN: %env_ubsan_opts=coverage=1:verbosity=1:coverage_dir='"%T/coverage-levels"' %run %t 2>&1 | FileCheck %s --check-prefix=CHECK2 --check-prefix=CHECK_WARN
+// RUN: %env_ubsan_opts=coverage=1:verbosity=1:coverage_dir='"%t-dir"' %run %t 2>&1 | FileCheck %s --check-prefix=CHECK2 --check-prefix=CHECK_WARN
// RUN: %clangxx -fsanitize=shift -O1 -fsanitize-coverage=edge %s -o %t
-// RUN: %env_ubsan_opts=coverage=1:verbosity=1:coverage_dir='"%T/coverage-levels"' %run %t 2>&1 | FileCheck %s --check-prefix=CHECK3 --check-prefix=CHECK_WARN
+// RUN: %env_ubsan_opts=coverage=1:verbosity=1:coverage_dir='"%t-dir"' %run %t 2>&1 | FileCheck %s --check-prefix=CHECK3 --check-prefix=CHECK_WARN
// Coverage is not yet implemented in TSan.
// XFAIL: ubsan-tsan
// UNSUPPORTED: ubsan-standalone-static
+// No coverage support
+// UNSUPPORTED: openbsd
volatile int sink;
int main(int argc, char **argv) {
diff --git a/test/ubsan/TestCases/Misc/missing_return.cpp b/test/ubsan/TestCases/Misc/missing_return.cpp
index 5c5b286f1a65..fe8c8bae603d 100644
--- a/test/ubsan/TestCases/Misc/missing_return.cpp
+++ b/test/ubsan/TestCases/Misc/missing_return.cpp
@@ -1,6 +1,8 @@
// RUN: %clangxx -fsanitize=return %gmlt %s -O3 -o %t
// RUN: not %run %t 2>&1 | FileCheck %s
// RUN: %env_ubsan_opts=print_stacktrace=1 not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-STACKTRACE
+// Error message does not exact what expected
+// XFAIL: openbsd
// CHECK: missing_return.cpp:[[@LINE+1]]:5: runtime error: execution reached the end of a value-returning function without returning a value
int f() {
diff --git a/test/ubsan/TestCases/Misc/monitor.cpp b/test/ubsan/TestCases/Misc/monitor.cpp
new file mode 100644
index 000000000000..6c5cacfed8be
--- /dev/null
+++ b/test/ubsan/TestCases/Misc/monitor.cpp
@@ -0,0 +1,44 @@
+// RUN: %clangxx -w -fsanitize=bool %s -o %t
+// RUN: %run %t 2>&1 | FileCheck %s
+
+// __ubsan_on_report is not defined as weak. Redefining it here isn't supported
+// on Windows.
+//
+// UNSUPPORTED: win32
+// Linkage issue
+// XFAIL: openbsd
+
+#include <cstdio>
+
+extern "C" {
+void __ubsan_get_current_report_data(const char **OutIssueKind,
+ const char **OutMessage,
+ const char **OutFilename,
+ unsigned *OutLine, unsigned *OutCol,
+ char **OutMemoryAddr);
+
+// Override the definition of __ubsan_on_report from the runtime, just for
+// testing purposes.
+void __ubsan_on_report(void) {
+ const char *IssueKind, *Message, *Filename;
+ unsigned Line, Col;
+ char *Addr;
+ __ubsan_get_current_report_data(&IssueKind, &Message, &Filename, &Line, &Col,
+ &Addr);
+
+ printf("Issue: %s\n", IssueKind);
+ printf("Location: %s:%u:%u\n", Filename, Line, Col);
+ printf("Message: %s\n", Message);
+
+ (void)Addr;
+}
+}
+
+int main() {
+ char C = 3;
+ bool B = *(bool *)&C;
+ // CHECK: Issue: invalid-bool-load
+ // CHECK-NEXT: Location: {{.*}}monitor.cpp:[[@LINE-2]]:12
+ // CHECK-NEXT: Message: Load of value 3, which is not a valid value for type 'bool'
+ return 0;
+}
diff --git a/test/ubsan/TestCases/TypeCheck/Function/function.cpp b/test/ubsan/TestCases/TypeCheck/Function/function.cpp
index 25b2bdc32c7a..7b9f0982639a 100644
--- a/test/ubsan/TestCases/TypeCheck/Function/function.cpp
+++ b/test/ubsan/TestCases/TypeCheck/Function/function.cpp
@@ -1,8 +1,10 @@
-// RUN: %clangxx -fsanitize=function %s -O3 -g -o %t
+// RUN: %clangxx -std=c++17 -fsanitize=function %s -O3 -g -o %t
// RUN: %run %t 2>&1 | FileCheck %s
// Verify that we can disable symbolization if needed:
// RUN: %env_ubsan_opts=symbolize=0 %run %t 2>&1 | FileCheck %s --check-prefix=NOSYM
// XFAIL: win32,win64
+// Unsupported function flag
+// UNSUPPORTED: openbsd
#include <stdint.h>
@@ -23,9 +25,49 @@ void make_invalid_call() {
reinterpret_cast<void (*)(int)>(reinterpret_cast<uintptr_t>(f))(42);
}
+void f1(int) {}
+void f2(unsigned int) {}
+void f3(int) noexcept {}
+void f4(unsigned int) noexcept {}
+
+void check_noexcept_calls() {
+ void (*p1)(int);
+ p1 = &f1;
+ p1(0);
+ p1 = reinterpret_cast<void (*)(int)>(&f2);
+ // CHECK: function.cpp:[[@LINE+2]]:3: runtime error: call to function f2(unsigned int) through pointer to incorrect function type 'void (*)(int)'
+ // NOSYM: function.cpp:[[@LINE+1]]:3: runtime error: call to function (unknown) through pointer to incorrect function type 'void (*)(int)'
+ p1(0);
+ p1 = &f3;
+ p1(0);
+ p1 = reinterpret_cast<void (*)(int)>(&f4);
+ // CHECK: function.cpp:[[@LINE+2]]:3: runtime error: call to function f4(unsigned int) through pointer to incorrect function type 'void (*)(int)'
+ // NOSYM: function.cpp:[[@LINE+1]]:3: runtime error: call to function (unknown) through pointer to incorrect function type 'void (*)(int)'
+ p1(0);
+
+ void (*p2)(int) noexcept;
+ p2 = reinterpret_cast<void (*)(int) noexcept>(&f1);
+ // TODO: Unclear whether calling a non-noexcept function through a pointer to
+ // nexcept function should cause an error.
+ // CHECK-NOT: function.cpp:[[@LINE+2]]:3: runtime error: call to function f1(int) through pointer to incorrect function type 'void (*)(int) noexcept'
+ // NOSYM-NOT: function.cpp:[[@LINE+1]]:3: runtime error: call to function (unknown) through pointer to incorrect function type 'void (*)(int) noexcept'
+ p2(0);
+ p2 = reinterpret_cast<void (*)(int) noexcept>(&f2);
+ // CHECK: function.cpp:[[@LINE+2]]:3: runtime error: call to function f2(unsigned int) through pointer to incorrect function type 'void (*)(int) noexcept'
+ // NOSYM: function.cpp:[[@LINE+1]]:3: runtime error: call to function (unknown) through pointer to incorrect function type 'void (*)(int) noexcept'
+ p2(0);
+ p2 = &f3;
+ p2(0);
+ p2 = reinterpret_cast<void (*)(int) noexcept>(&f4);
+ // CHECK: function.cpp:[[@LINE+2]]:3: runtime error: call to function f4(unsigned int) through pointer to incorrect function type 'void (*)(int) noexcept'
+ // NOSYM: function.cpp:[[@LINE+1]]:3: runtime error: call to function (unknown) through pointer to incorrect function type 'void (*)(int) noexcept'
+ p2(0);
+}
+
int main(void) {
make_valid_call();
make_invalid_call();
+ check_noexcept_calls();
// Check that no more errors will be printed.
// CHECK-NOT: runtime error: call to function
// NOSYM-NOT: runtime error: call to function
diff --git a/test/ubsan/TestCases/TypeCheck/misaligned.cpp b/test/ubsan/TestCases/TypeCheck/misaligned.cpp
index 4eaedf37e565..a5cefaa31cd6 100644
--- a/test/ubsan/TestCases/TypeCheck/misaligned.cpp
+++ b/test/ubsan/TestCases/TypeCheck/misaligned.cpp
@@ -11,6 +11,8 @@
// RUN: %clangxx -fsanitize=alignment -fno-sanitize-recover=alignment %s -O3 -o %t
// RUN: not %run %t w1 2>&1 | FileCheck %s --check-prefix=CHECK-WILD
+// Compilation error make the test fails.
+// XFAIL: openbsd
#include <new>
diff --git a/test/ubsan/TestCases/TypeCheck/vptr.cpp b/test/ubsan/TestCases/TypeCheck/vptr.cpp
index d7848c4ce3f9..9b53e8095777 100644
--- a/test/ubsan/TestCases/TypeCheck/vptr.cpp
+++ b/test/ubsan/TestCases/TypeCheck/vptr.cpp
@@ -40,6 +40,8 @@
// UNSUPPORTED: win32
// Suppressions file not pushed to the device.
// UNSUPPORTED: android
+// Compilation error
+// UNSUPPORTED: openbsd
#include <new>
#include <typeinfo>
#include <assert.h>
diff --git a/test/ubsan/lit.common.cfg b/test/ubsan/lit.common.cfg
index 83475a2dc36c..e20832bd655f 100644
--- a/test/ubsan/lit.common.cfg
+++ b/test/ubsan/lit.common.cfg
@@ -68,7 +68,7 @@ config.substitutions.append( ("%gmlt ", " ".join(config.debug_info_flags) + " ")
config.suffixes = ['.c', '.cc', '.cpp']
# Check that the host supports UndefinedBehaviorSanitizer tests
-if config.host_os not in ['Linux', 'Darwin', 'FreeBSD', 'Windows', 'NetBSD']:
+if config.host_os not in ['Linux', 'Darwin', 'FreeBSD', 'Windows', 'NetBSD', 'SunOS', 'OpenBSD']:
config.unsupported = True
config.available_features.add('arch=' + config.target_arch)
diff --git a/test/ubsan_minimal/CMakeLists.txt b/test/ubsan_minimal/CMakeLists.txt
index 712654e94518..5da5fcd02b94 100644
--- a/test/ubsan_minimal/CMakeLists.txt
+++ b/test/ubsan_minimal/CMakeLists.txt
@@ -4,6 +4,9 @@ set(UBSAN_TEST_ARCH ${UBSAN_SUPPORTED_ARCH})
if(APPLE)
darwin_filter_host_archs(UBSAN_SUPPORTED_ARCH UBSAN_TEST_ARCH)
endif()
+if(OS_NAME MATCHES "SunOS")
+ list(REMOVE_ITEM UBSAN_TEST_ARCH x86_64)
+endif()
set(UBSAN_TESTSUITES)
set(UBSAN_TEST_DEPS ${SANITIZER_COMMON_LIT_TEST_DEPS})
diff --git a/test/ubsan_minimal/lit.common.cfg b/test/ubsan_minimal/lit.common.cfg
index e8b42bb823c8..a436a315f0a6 100644
--- a/test/ubsan_minimal/lit.common.cfg
+++ b/test/ubsan_minimal/lit.common.cfg
@@ -30,7 +30,7 @@ config.substitutions.append( ("%clangxx ", build_invocation(clang_ubsan_cxxflags
config.suffixes = ['.c', '.cc', '.cpp']
# Check that the host supports UndefinedBehaviorSanitizerMinimal tests
-if config.host_os not in ['Linux', 'FreeBSD', 'NetBSD', 'Darwin']: # TODO: Windows
+if config.host_os not in ['Linux', 'FreeBSD', 'NetBSD', 'Darwin', 'OpenBSD']: # TODO: Windows
config.unsupported = True
# Don't target x86_64h if the test machine can't execute x86_64h binaries.
diff --git a/test/xray/CMakeLists.txt b/test/xray/CMakeLists.txt
index b51b3cd0ccd8..d049ac0f979f 100644
--- a/test/xray/CMakeLists.txt
+++ b/test/xray/CMakeLists.txt
@@ -28,11 +28,13 @@ if (COMPILER_RT_BUILD_XRAY AND COMPILER_RT_HAS_XRAY)
# Add unit tests.
if(COMPILER_RT_INCLUDE_TESTS)
- configure_lit_site_cfg(
- ${CMAKE_CURRENT_SOURCE_DIR}/Unit/lit.site.cfg.in
- ${CMAKE_CURRENT_BINARY_DIR}/Unit/lit.site.cfg)
- list(APPEND XRAY_TEST_DEPS XRayUnitTests)
- list(APPEND XRAY_TESTSUITES ${CMAKE_CURRENT_BINARY_DIR}/Unit)
+ if(UNIX AND NOT APPLE)
+ configure_lit_site_cfg(
+ ${CMAKE_CURRENT_SOURCE_DIR}/Unit/lit.site.cfg.in
+ ${CMAKE_CURRENT_BINARY_DIR}/Unit/lit.site.cfg)
+ list(APPEND XRAY_TEST_DEPS XRayUnitTests)
+ list(APPEND XRAY_TESTSUITES ${CMAKE_CURRENT_BINARY_DIR}/Unit)
+ endif()
endif()
endif()
diff --git a/test/xray/TestCases/Linux/always-never-instrument.cc b/test/xray/TestCases/Posix/always-never-instrument.cc
index 4e196859bcda..fd9299b756bb 100644
--- a/test/xray/TestCases/Linux/always-never-instrument.cc
+++ b/test/xray/TestCases/Posix/always-never-instrument.cc
@@ -9,7 +9,7 @@
// RUN: FileCheck %s --check-prefix NOINSTR
// RUN: %llvm_xray extract -symbolize %t | \
// RUN: FileCheck %s --check-prefix ALWAYSINSTR
-// REQUIRES: x86_64-linux
+// REQUIRES: x86_64-target-arch
// REQUIRES: built-in-llvm-tree
// NOINSTR-NOT: {{.*__xray_NeverInstrumented.*}}
diff --git a/test/xray/TestCases/Linux/arg1-arg0-logging.cc b/test/xray/TestCases/Posix/arg1-arg0-logging.cc
index e7730bfa6172..757f81a8babb 100644
--- a/test/xray/TestCases/Linux/arg1-arg0-logging.cc
+++ b/test/xray/TestCases/Posix/arg1-arg0-logging.cc
@@ -1,7 +1,7 @@
// Allow having both the no-arg and arg1 logging implementation live together,
// and be called in the correct cases.
//
-// RUN: rm arg0-arg1-logging-* || true
+// RUN: rm -f arg0-arg1-logging-*
// RUN: %clangxx_xray -std=c++11 %s -o %t
// RUN: XRAY_OPTIONS="patch_premain=true verbosity=1 xray_logfile_base=arg0-arg1-logging-" %run %t
//
diff --git a/test/xray/TestCases/Linux/arg1-logger.cc b/test/xray/TestCases/Posix/arg1-logger.cc
index 25dda13fb23d..a6ca0a495250 100644
--- a/test/xray/TestCases/Linux/arg1-logger.cc
+++ b/test/xray/TestCases/Posix/arg1-logger.cc
@@ -2,13 +2,13 @@
// using a custom logging function.
//
// RUN: %clangxx_xray -std=c++11 %s -o %t
-// RUN: rm arg1-logger-* || true
+// RUN: rm -f arg1-logger-*
// RUN: XRAY_OPTIONS="patch_premain=true verbosity=1 xray_naive_log=true \
// RUN: xray_logfile_base=arg1-logger-" %run %t 2>&1 | FileCheck %s
//
// After all that, clean up the XRay log file.
//
-// RUN: rm arg1-logger-* || true
+// RUN: rm -f arg1-logger-*
//
// At the time of writing, the ARM trampolines weren't written yet.
// XFAIL: arm || aarch64 || mips
diff --git a/test/xray/TestCases/Linux/arg1-logging-implicit-this.cc b/test/xray/TestCases/Posix/arg1-logging-implicit-this.cc
index 66dfce9a3b7d..d8dd62247bff 100644
--- a/test/xray/TestCases/Linux/arg1-logging-implicit-this.cc
+++ b/test/xray/TestCases/Posix/arg1-logging-implicit-this.cc
@@ -1,10 +1,10 @@
// Intercept the implicit 'this' argument of class member functions.
//
// RUN: %clangxx_xray -g -std=c++11 %s -o %t
-// RUN: rm log-args-this-* || true
+// RUN: rm -f log-args-this-*
// RUN: XRAY_OPTIONS="patch_premain=true verbosity=1 xray_logfile_base=log-args-this-" %run %t
//
-// XFAIL: arm || aarch64 || mips
+// XFAIL: FreeBSD || arm || aarch64 || mips
// UNSUPPORTED: powerpc64le
#include "xray/xray_interface.h"
#include <cassert>
diff --git a/test/xray/TestCases/Linux/argv0-log-file-name.cc b/test/xray/TestCases/Posix/argv0-log-file-name.cc
index 2f9a234f8064..2f9a234f8064 100644
--- a/test/xray/TestCases/Linux/argv0-log-file-name.cc
+++ b/test/xray/TestCases/Posix/argv0-log-file-name.cc
diff --git a/test/xray/TestCases/Linux/basic-filtering.cc b/test/xray/TestCases/Posix/basic-filtering.cc
index b758859cf6cb..db07ef510c5c 100644
--- a/test/xray/TestCases/Linux/basic-filtering.cc
+++ b/test/xray/TestCases/Posix/basic-filtering.cc
@@ -2,8 +2,8 @@
// logging implementation.
// RUN: %clangxx_xray -std=c++11 %s -o %t -g
-// RUN: rm basic-filtering-* || true
-// RUN: XRAY_OPTIONS="patch_premain=true xray_naive_log=true verbosity=1 \
+// RUN: rm -f basic-filtering-*
+// RUN: XRAY_OPTIONS="patch_premain=true xray_mode=xray-basic verbosity=1 \
// RUN: xray_logfile_base=basic-filtering- \
// RUN: xray_naive_log_func_duration_threshold_us=1000 \
// RUN: xray_naive_log_max_stack_depth=2" %run %t 2>&1 | \
@@ -11,9 +11,19 @@
// RUN: %llvm_xray convert --symbolize --output-format=yaml -instr_map=%t \
// RUN: "`ls basic-filtering-* | head -1`" | \
// RUN: FileCheck %s --check-prefix TRACE
-// RUN: rm basic-filtering-* || true
+// RUN: rm -f basic-filtering-*
//
-// REQUIRES: x86_64-linux
+// Now check support for the XRAY_BASIC_OPTIONS environment variable.
+// RUN: XRAY_OPTIONS="patch_premain=true xray_mode=xray-basic verbosity=1 \
+// RUN: xray_logfile_base=basic-filtering-" \
+// RUN: XRAY_BASIC_OPTIONS="func_duration_threshold_us=1000 max_stack_depth=2" \
+// RUN: %run %t 2>&1 | FileCheck %s
+// RUN: %llvm_xray convert --symbolize --output-format=yaml -instr_map=%t \
+// RUN: "`ls basic-filtering-* | head -1`" | \
+// RUN: FileCheck %s --check-prefix TRACE
+// RUN: rm -f basic-filtering-*
+//
+// REQUIRES: x86_64-target-arch
// REQUIRES: built-in-llvm-tree
#include <cstdio>
diff --git a/test/xray/TestCases/Posix/c-test.cc b/test/xray/TestCases/Posix/c-test.cc
new file mode 100644
index 000000000000..28a7870d0f74
--- /dev/null
+++ b/test/xray/TestCases/Posix/c-test.cc
@@ -0,0 +1,15 @@
+// RUN: %clang_xray -g -fxray-modes=xray-basic,xray-fdr,xray-profiling -o %t %s
+// RUN: rm -f xray-log.c-test.*
+// RUN: XRAY_OPTIONS=patch_premain=true:verbosity=1:xray_mode=xray-basic %t \
+// RUN: 2>&1 | FileCheck %s
+// RUN: rm -f xray-log.c-test.*
+//
+// REQUIRES: x86_64-target-arch
+// REQUIRES: built-in-llvm-tree
+__attribute__((xray_always_instrument)) void always() {}
+
+int main() {
+ always();
+}
+
+// CHECK: =={{[0-9].*}}==XRay: Log file in '{{.*}}'
diff --git a/test/xray/TestCases/Linux/common-trampoline-alignment.cc b/test/xray/TestCases/Posix/common-trampoline-alignment.cc
index 5d1cc1e9b451..dac0789abdec 100644
--- a/test/xray/TestCases/Linux/common-trampoline-alignment.cc
+++ b/test/xray/TestCases/Posix/common-trampoline-alignment.cc
@@ -4,7 +4,7 @@
// RUN: %clangxx_xray -std=c++11 %s -o %t
// RUN: XRAY_OPTIONS="patch_premain=false verbosity=1 xray_naive_log=false" \
// RUN: %run %t 2>&1
-// REQUIRES: x86_64-linux
+// REQUIRES: x86_64-target-arch
// REQUIRES: built-in-llvm-tree
#include "xray/xray_interface.h"
#include <stdio.h>
diff --git a/test/xray/TestCases/Linux/coverage-sample.cc b/test/xray/TestCases/Posix/coverage-sample.cc
index 62c13ba3d42a..62c13ba3d42a 100644
--- a/test/xray/TestCases/Linux/coverage-sample.cc
+++ b/test/xray/TestCases/Posix/coverage-sample.cc
diff --git a/test/xray/TestCases/Linux/custom-event-handler-alignment.cc b/test/xray/TestCases/Posix/custom-event-handler-alignment.cc
index 447f6e4f2b42..c8de18b0e2b6 100644
--- a/test/xray/TestCases/Linux/custom-event-handler-alignment.cc
+++ b/test/xray/TestCases/Posix/custom-event-handler-alignment.cc
@@ -4,7 +4,7 @@
// RUN: %clangxx_xray -std=c++11 %s -o %t
// RUN: XRAY_OPTIONS="patch_premain=false verbosity=1 xray_naive_log=false" \
// RUN: %run %t 2>&1
-// REQUIRES: x86_64-linux
+// REQUIRES: x86_64-target-arch
// REQUIRES: built-in-llvm-tree
#include <xmmintrin.h>
#include <stdio.h>
diff --git a/test/xray/TestCases/Linux/custom-event-logging.cc b/test/xray/TestCases/Posix/custom-event-logging.cc
index 48fd62034194..48fd62034194 100644
--- a/test/xray/TestCases/Linux/custom-event-logging.cc
+++ b/test/xray/TestCases/Posix/custom-event-logging.cc
diff --git a/test/xray/TestCases/Posix/fdr-mode-inmemory.cc b/test/xray/TestCases/Posix/fdr-mode-inmemory.cc
new file mode 100644
index 000000000000..ff31626d7779
--- /dev/null
+++ b/test/xray/TestCases/Posix/fdr-mode-inmemory.cc
@@ -0,0 +1,50 @@
+// RUN: %clangxx_xray -g -std=c++11 %s -o %t -fxray-modes=xray-fdr
+// RUN: rm -f fdr-inmemory-test-*
+// RUN: XRAY_OPTIONS="patch_premain=false xray_logfile_base=fdr-inmemory-test- \
+// RUN: verbosity=1" \
+// RUN: XRAY_FDR_OPTIONS="no_file_flush=true func_duration_threshold_us=0" \
+// RUN: %run %t 2>&1 | FileCheck %s
+// RUN: FILES=`find %T -name 'fdr-inmemory-test-*' | wc -l`
+// RUN: [ $FILES -eq 0 ]
+// RUN: rm -f fdr-inmemory-test-*
+//
+// REQUIRES: x86_64-target-arch
+// REQUIRES: built-in-llvm-tree
+
+#include "xray/xray_log_interface.h"
+#include <cassert>
+#include <iostream>
+
+uint64_t var = 0;
+uint64_t buffers = 0;
+[[clang::xray_always_instrument]] void __attribute__((noinline)) f() { ++var; }
+
+int main(int argc, char *argv[]) {
+ assert(__xray_log_select_mode("xray-fdr") ==
+ XRayLogRegisterStatus::XRAY_REGISTRATION_OK);
+ auto status = __xray_log_init_mode(
+ "xray-fdr",
+ "buffer_size=4096:buffer_max=10:func_duration_threshold_us=0");
+ assert(status == XRayLogInitStatus::XRAY_LOG_INITIALIZED);
+ __xray_patch();
+
+ // Create enough entries.
+ for (int i = 0; i != 1 << 20; ++i) {
+ f();
+ }
+
+ // Then we want to verify that we're getting 10 buffers outside of the initial
+ // header.
+ auto finalize_status = __xray_log_finalize();
+ assert(finalize_status == XRayLogInitStatus::XRAY_LOG_FINALIZED);
+ auto process_status =
+ __xray_log_process_buffers([](const char *, XRayBuffer) { ++buffers; });
+ std::cout << "buffers = " << buffers << std::endl;
+ assert(process_status == XRayLogFlushStatus::XRAY_LOG_FLUSHED);
+ auto flush_status = __xray_log_flushLog();
+ assert(flush_status == XRayLogFlushStatus::XRAY_LOG_FLUSHED);
+ // We expect 11 buffers because 1 header buffer + 10 actual FDR buffers.
+ // CHECK: Buffers = 11
+ std::cout << "Buffers = " << buffers << std::endl;
+ return 0;
+}
diff --git a/test/xray/TestCases/Posix/fdr-mode-multiple.cc b/test/xray/TestCases/Posix/fdr-mode-multiple.cc
new file mode 100644
index 000000000000..487e3031325e
--- /dev/null
+++ b/test/xray/TestCases/Posix/fdr-mode-multiple.cc
@@ -0,0 +1,76 @@
+// RUN: %clangxx_xray -g -std=c++11 %s -o %t -fxray-modes=xray-fdr
+// RUN: rm -f fdr-inmemory-test-*
+// RUN: XRAY_OPTIONS="patch_premain=false xray_logfile_base=fdr-inmemory-test- \
+// RUN: verbosity=1" \
+// RUN: XRAY_FDR_OPTIONS="no_file_flush=true func_duration_threshold_us=0" \
+// RUN: %run %t 2>&1 | FileCheck %s
+// RUN: FILES=`find %T -name 'fdr-inmemory-test-*' | wc -l`
+// RUN: [ $FILES -eq 0 ]
+// RUN: rm -f fdr-inmemory-test-*
+//
+// REQUIRES: x86_64-target-arch
+// REQUIRES: built-in-llvm-tree
+
+#include "xray/xray_log_interface.h"
+#include <cassert>
+#include <iostream>
+
+uint64_t var = 0;
+uint64_t buffers = 0;
+[[clang::xray_always_instrument]] void __attribute__((noinline)) f() { ++var; }
+
+int main(int argc, char *argv[]) {
+ assert(__xray_log_select_mode("xray-fdr") ==
+ XRayLogRegisterStatus::XRAY_REGISTRATION_OK);
+ auto status = __xray_log_init_mode(
+ "xray-fdr",
+ "buffer_size=4096:buffer_max=10:func_duration_threshold_us=0");
+ assert(status == XRayLogInitStatus::XRAY_LOG_INITIALIZED);
+ __xray_patch();
+
+ // Create enough entries.
+ for (int i = 0; i != 1 << 20; ++i) {
+ f();
+ }
+
+ // Then we want to verify that we're getting 10 buffers outside of the initial
+ // header.
+ auto finalize_status = __xray_log_finalize();
+ assert(finalize_status == XRayLogInitStatus::XRAY_LOG_FINALIZED);
+ auto process_status =
+ __xray_log_process_buffers([](const char *, XRayBuffer) { ++buffers; });
+ std::cout << "buffers = " << buffers << std::endl;
+ assert(process_status == XRayLogFlushStatus::XRAY_LOG_FLUSHED);
+ auto flush_status = __xray_log_flushLog();
+ assert(flush_status == XRayLogFlushStatus::XRAY_LOG_FLUSHED);
+ // We expect 11 buffers because 1 header buffer + 10 actual FDR buffers.
+ // CHECK: Buffers = 11
+ std::cout << "Buffers = " << buffers << std::endl;
+
+ // In this test we ensure that we can restart the cycle after the flush.
+ status = __xray_log_init_mode(
+ "xray-fdr",
+ "buffer_size=4096:buffer_max=10:func_duration_threshold_us=0");
+ assert(status == XRayLogInitStatus::XRAY_LOG_INITIALIZED);
+ __xray_patch();
+
+ // Create enough entries.
+ for (int i = 0; i != 1 << 20; ++i) {
+ f();
+ }
+
+ // Then we want to verify that we're getting 10 buffers outside of the initial
+ // header.
+ finalize_status = __xray_log_finalize();
+ assert(finalize_status == XRayLogInitStatus::XRAY_LOG_FINALIZED);
+ process_status =
+ __xray_log_process_buffers([](const char *, XRayBuffer) { ++buffers; });
+ std::cout << "buffers = " << buffers << std::endl;
+ assert(process_status == XRayLogFlushStatus::XRAY_LOG_FLUSHED);
+ flush_status = __xray_log_flushLog();
+ assert(flush_status == XRayLogFlushStatus::XRAY_LOG_FLUSHED);
+ // We expect 22 buffers because 1 header buffer + 10 actual FDR buffers, plus
+ // the number of buffers we got from the previous run (also 11).
+ // CHECK: Buffers = 22
+ std::cout << "Buffers = " << buffers << std::endl;
+}
diff --git a/test/xray/TestCases/Linux/fdr-mode.cc b/test/xray/TestCases/Posix/fdr-mode.cc
index 744c051cfb2c..b12d97c0005a 100644
--- a/test/xray/TestCases/Linux/fdr-mode.cc
+++ b/test/xray/TestCases/Posix/fdr-mode.cc
@@ -1,14 +1,25 @@
// RUN: %clangxx_xray -g -std=c++11 %s -o %t
-// RUN: rm fdr-logging-test-* || true
-// RUN: rm fdr-unwrite-test-* || true
-// RUN: XRAY_OPTIONS="patch_premain=false xray_naive_log=false xray_logfile_base=fdr-logging-test- xray_fdr_log=true verbosity=1 xray_fdr_log_func_duration_threshold_us=0" %run %t 2>&1 | FileCheck %s
-// RUN: XRAY_OPTIONS="patch_premain=false xray_naive_log=false xray_logfile_base=fdr-unwrite-test- xray_fdr_log=true verbosity=1 xray_fdr_log_func_duration_threshold_us=5000" %run %t 2>&1 | FileCheck %s
-// RUN: %llvm_xray convert --symbolize --output-format=yaml -instr_map=%t "`ls fdr-logging-test-* | head -1`" | FileCheck %s --check-prefix=TRACE
-// RUN: %llvm_xray convert --symbolize --output-format=yaml -instr_map=%t "`ls fdr-unwrite-test-* | head -1`" | FileCheck %s --check-prefix=UNWRITE
+// RUN: rm -f fdr-logging-test-*
+// RUN: rm -f fdr-unwrite-test-*
+// RUN: XRAY_OPTIONS="patch_premain=false xray_logfile_base=fdr-logging-test- \
+// RUN: xray_mode=xray-fdr verbosity=1" \
+// RUN: XRAY_FDR_OPTIONS="func_duration_threshold_us=0" \
+// RUN: %run %t 2>&1 | FileCheck %s
+// RUN: XRAY_OPTIONS="patch_premain=false \
+// RUN: xray_logfile_base=fdr-unwrite-test- xray_mode=xray-fdr \
+// RUN: verbosity=1" \
+// RUN: XRAY_FDR_OPTIONS="func_duration_threshold_us=5000" \
+// RUN: %run %t 2>&1 | FileCheck %s
+// RUN: %llvm_xray convert --symbolize --output-format=yaml -instr_map=%t \
+// RUN: "`ls fdr-logging-test-* | head -1`" \
+// RUN: | FileCheck %s --check-prefix=TRACE
+// RUN: %llvm_xray convert --symbolize --output-format=yaml -instr_map=%t \
+// RUN: "`ls fdr-unwrite-test-* | head -1`" \
+// RUN: | FileCheck %s --check-prefix=UNWRITE
// RUN: rm fdr-logging-test-*
// RUN: rm fdr-unwrite-test-*
// FIXME: Make llvm-xray work on non-x86_64 as well.
-// REQUIRES: x86_64-linux
+// REQUIRES: x86_64-target-arch
// REQUIRES: built-in-llvm-tree
#include "xray/xray_log_interface.h"
@@ -20,9 +31,6 @@
#include <thread>
#include <time.h>
-constexpr auto kBufferSize = 16384;
-constexpr auto kBufferMax = 10;
-
thread_local uint64_t var = 0;
[[clang::xray_always_instrument]] void __attribute__((noinline)) fC() { ++var; }
@@ -35,11 +43,12 @@ void __attribute__((noinline)) fArg(int) { }
int main(int argc, char *argv[]) {
using namespace __xray;
- FDRLoggingOptions Options;
std::cout << "Logging before init." << std::endl;
// CHECK: Logging before init.
- auto status = __xray_log_init(kBufferSize, kBufferMax, &Options,
- sizeof(FDRLoggingOptions));
+ assert(__xray_log_select_mode("xray-fdr") ==
+ XRayLogRegisterStatus::XRAY_REGISTRATION_OK);
+ auto status =
+ __xray_log_init_mode("xray-fdr", "buffer_size=16384:buffer_max=10");
assert(status == XRayLogInitStatus::XRAY_LOG_INITIALIZED);
std::cout << "Init status " << status << std::endl;
// CHECK: Init status {{.*}}
@@ -72,32 +81,32 @@ int main(int argc, char *argv[]) {
}
// Check that we're able to see two threads, each entering and exiting fA().
-// TRACE-DAG: - { type: 0, func-id: [[FIDA:[0-9]+]], function: {{.*fA.*}}, cpu: {{.*}}, thread: [[THREAD1:[0-9]+]], kind: function-enter, tsc: {{[0-9]+}} }
-// TRACE: - { type: 0, func-id: [[FIDA]], function: {{.*fA.*}}, cpu: {{.*}}, thread: [[THREAD1]], kind: function-{{exit|tail-exit}}, tsc: {{[0-9]+}} }
-// TRACE-DAG: - { type: 0, func-id: [[FIDA]], function: {{.*fA.*}}, cpu: {{.*}}, thread: [[THREAD2:[0-9]+]], kind: function-enter, tsc: {{[0-9]+}} }
-// TRACE: - { type: 0, func-id: [[FIDA]], function: {{.*fA.*}}, cpu: {{.*}}, thread: [[THREAD2]], kind: function-{{exit|tail-exit}}, tsc: {{[0-9]+}} }
+// TRACE-DAG: - { type: 0, func-id: [[FIDA:[0-9]+]], function: {{.*fA.*}}, cpu: {{.*}}, thread: [[THREAD1:[0-9]+]], process: [[PROCESS:[0-9]+]], kind: function-enter, tsc: {{[0-9]+}} }
+// TRACE: - { type: 0, func-id: [[FIDA]], function: {{.*fA.*}}, cpu: {{.*}}, thread: [[THREAD1]], process: [[PROCESS]], kind: function-{{exit|tail-exit}}, tsc: {{[0-9]+}} }
+// TRACE-DAG: - { type: 0, func-id: [[FIDA]], function: {{.*fA.*}}, cpu: {{.*}}, thread: [[THREAD2:[0-9]+]], process: [[PROCESS]], kind: function-enter, tsc: {{[0-9]+}} }
+// TRACE: - { type: 0, func-id: [[FIDA]], function: {{.*fA.*}}, cpu: {{.*}}, thread: [[THREAD2]], process: [[PROCESS]], kind: function-{{exit|tail-exit}}, tsc: {{[0-9]+}} }
//
// Do the same as above for fC()
-// TRACE-DAG: - { type: 0, func-id: [[FIDC:[0-9]+]], function: {{.*fC.*}}, cpu: {{.*}}, thread: [[THREAD1:[0-9]+]], kind: function-enter, tsc: {{[0-9]+}} }
-// TRACE: - { type: 0, func-id: [[FIDC]], function: {{.*fC.*}}, cpu: {{.*}}, thread: [[THREAD1]], kind: function-{{exit|tail-exit}}, tsc: {{[0-9]+}} }
-// TRACE-DAG: - { type: 0, func-id: [[FIDC]], function: {{.*fC.*}}, cpu: {{.*}}, thread: [[THREAD2:[0-9]+]], kind: function-enter, tsc: {{[0-9]+}} }
-// TRACE: - { type: 0, func-id: [[FIDC]], function: {{.*fC.*}}, cpu: {{.*}}, thread: [[THREAD2]], kind: function-{{exit|tail-exit}}, tsc: {{[0-9]+}} }
+// TRACE-DAG: - { type: 0, func-id: [[FIDC:[0-9]+]], function: {{.*fC.*}}, cpu: {{.*}}, thread: [[THREAD1:[0-9]+]], process: [[PROCESS]], kind: function-enter, tsc: {{[0-9]+}} }
+// TRACE: - { type: 0, func-id: [[FIDC]], function: {{.*fC.*}}, cpu: {{.*}}, thread: [[THREAD1]], process: [[PROCESS]], kind: function-{{exit|tail-exit}}, tsc: {{[0-9]+}} }
+// TRACE-DAG: - { type: 0, func-id: [[FIDC]], function: {{.*fC.*}}, cpu: {{.*}}, thread: [[THREAD2:[0-9]+]], process: [[PROCESS]], kind: function-enter, tsc: {{[0-9]+}} }
+// TRACE: - { type: 0, func-id: [[FIDC]], function: {{.*fC.*}}, cpu: {{.*}}, thread: [[THREAD2]], process: [[PROCESS]], kind: function-{{exit|tail-exit}}, tsc: {{[0-9]+}} }
// Do the same as above for fB()
-// TRACE-DAG: - { type: 0, func-id: [[FIDB:[0-9]+]], function: {{.*fB.*}}, cpu: {{.*}}, thread: [[THREAD1:[0-9]+]], kind: function-enter, tsc: {{[0-9]+}} }
-// TRACE: - { type: 0, func-id: [[FIDB]], function: {{.*fB.*}}, cpu: {{.*}}, thread: [[THREAD1]], kind: function-{{exit|tail-exit}}, tsc: {{[0-9]+}} }
-// TRACE-DAG: - { type: 0, func-id: [[FIDB]], function: {{.*fB.*}}, cpu: {{.*}}, thread: [[THREAD2:[0-9]+]], kind: function-enter, tsc: {{[0-9]+}} }
-// TRACE: - { type: 0, func-id: [[FIDB]], function: {{.*fB.*}}, cpu: {{.*}}, thread: [[THREAD2]], kind: function-{{exit|tail-exit}}, tsc: {{[0-9]+}} }
+// TRACE-DAG: - { type: 0, func-id: [[FIDB:[0-9]+]], function: {{.*fB.*}}, cpu: {{.*}}, thread: [[THREAD1:[0-9]+]], process: [[PROCESS]], kind: function-enter, tsc: {{[0-9]+}} }
+// TRACE: - { type: 0, func-id: [[FIDB]], function: {{.*fB.*}}, cpu: {{.*}}, thread: [[THREAD1]], process: [[PROCESS]], kind: function-{{exit|tail-exit}}, tsc: {{[0-9]+}} }
+// TRACE-DAG: - { type: 0, func-id: [[FIDB]], function: {{.*fB.*}}, cpu: {{.*}}, thread: [[THREAD2:[0-9]+]], process: [[PROCESS]], kind: function-enter, tsc: {{[0-9]+}} }
+// TRACE: - { type: 0, func-id: [[FIDB]], function: {{.*fB.*}}, cpu: {{.*}}, thread: [[THREAD2]], process: [[PROCESS]], kind: function-{{exit|tail-exit}}, tsc: {{[0-9]+}} }
-// TRACE-DAG: - { type: 0, func-id: [[FIDARG:[0-9]+]], function: 'fArg(int)', args: [ 1 ], cpu: {{.*}}, thread: [[THREAD2]], kind: function-enter-arg, tsc: {{[0-9]+}} }
-// TRACE-DAG: - { type: 0, func-id: [[FIDARG]], function: 'fArg(int)', cpu: {{.*}}, thread: [[THREAD2]], kind: function-exit, tsc: {{[0-9]+}} }
+// TRACE-DAG: - { type: 0, func-id: [[FIDARG:[0-9]+]], function: 'fArg(int)', args: [ 1 ], cpu: {{.*}}, thread: [[THREAD2]], process: [[PROCESS]], kind: function-enter-arg, tsc: {{[0-9]+}} }
+// TRACE-DAG: - { type: 0, func-id: [[FIDARG]], function: 'fArg(int)', cpu: {{.*}}, thread: [[THREAD2]], process: [[PROCESS]], kind: function-exit, tsc: {{[0-9]+}} }
// Assert that when unwriting is enabled with a high threshold time, all the function records are erased. A CPU switch could erroneously fail this test, but
// is unlikely given the test program.
// Even with a high threshold, arg1 logging is never unwritten.
// UNWRITE: header:
// UNWRITE: records:
-// UNWRITE-NEXT: - { type: 0, func-id: [[FIDARG:[0-9]+]], function: 'fArg(int)', args: [ 1 ], cpu: {{.*}}, thread: [[THREAD2:[0-9]+]], kind: function-enter-arg, tsc: {{[0-9]+}} }
-// UNWRITE-NEXT: - { type: 0, func-id: [[FIDARG]], function: 'fArg(int)', cpu: {{.*}}, thread: [[THREAD2]], kind: function-exit, tsc: {{[0-9]+}} }
+// UNWRITE-NEXT: - { type: 0, func-id: [[FIDARG:[0-9]+]], function: 'fArg(int)', args: [ 1 ], cpu: {{.*}}, thread: [[THREAD2:[0-9]+]], process: [[PROCESS:[0-9]+]], kind: function-enter-arg, tsc: {{[0-9]+}} }
+// UNWRITE-NEXT: - { type: 0, func-id: [[FIDARG]], function: 'fArg(int)', cpu: {{.*}}, thread: [[THREAD2]], process: [[PROCESS]], kind: function-exit, tsc: {{[0-9]+}} }
// UNWRITE-NOT: function-enter
// UNWRITE-NOT: function-{{exit|tail-exit}}
diff --git a/test/xray/TestCases/Linux/fdr-single-thread.cc b/test/xray/TestCases/Posix/fdr-single-thread.cc
index dd50f485f82b..480502b0a60f 100644
--- a/test/xray/TestCases/Linux/fdr-single-thread.cc
+++ b/test/xray/TestCases/Posix/fdr-single-thread.cc
@@ -1,5 +1,5 @@
// RUN: %clangxx_xray -g -std=c++11 %s -o %t
-// RUN: rm fdr-logging-1thr-* || true
+// RUN: rm -f fdr-logging-1thr-*
// RUN: XRAY_OPTIONS=XRAY_OPTIONS="verbosity=1 patch_premain=true \
// RUN: xray_naive_log=false xray_fdr_log=true \
// RUN: xray_fdr_log_func_duration_threshold_us=0 \
@@ -8,7 +8,7 @@
// RUN: "`ls fdr-logging-1thr-* | head -n1`" | FileCheck %s
// RUN: rm fdr-logging-1thr-*
//
-// REQUIRES: x86_64-linux
+// REQUIRES: x86_64-target-arch
#include "xray/xray_log_interface.h"
#include <cassert>
@@ -34,5 +34,5 @@ int main(int argc, char *argv[]) {
}
// CHECK: records:
-// CHECK-NEXT: - { type: 0, func-id: [[FID1:[0-9]+]], function: {{.*fn.*}}, cpu: {{.*}}, thread: [[THREAD1:[0-9]+]], kind: function-enter, tsc: {{[0-9]+}} }
-// CHECK-NEXT: - { type: 0, func-id: [[FID1:[0-9]+]], function: {{.*fn.*}}, cpu: {{.*}}, thread: [[THREAD1:[0-9]+]], kind: function-exit, tsc: {{[0-9]+}} }
+// CHECK-NEXT: - { type: 0, func-id: [[FID1:[0-9]+]], function: {{.*fn.*}}, cpu: {{.*}}, thread: [[THREAD1:[0-9]+]], process: [[PROCESS:[0-9]+]], kind: function-enter, tsc: {{[0-9]+}} }
+// CHECK-NEXT: - { type: 0, func-id: [[FID1:[0-9]+]], function: {{.*fn.*}}, cpu: {{.*}}, thread: [[THREAD1:[0-9]+]], process: [[PROCESS:[0-9]+]], kind: function-exit, tsc: {{[0-9]+}} }
diff --git a/test/xray/TestCases/Linux/fdr-thread-order.cc b/test/xray/TestCases/Posix/fdr-thread-order.cc
index 8e8c421dcc66..1d6b01759f14 100644
--- a/test/xray/TestCases/Linux/fdr-thread-order.cc
+++ b/test/xray/TestCases/Posix/fdr-thread-order.cc
@@ -11,7 +11,7 @@
// RUN: FileCheck %s --check-prefix TRACE
// RUN: rm fdr-thread-order.*
// FIXME: Make llvm-xray work on non-x86_64 as well.
-// REQUIRES: x86_64-linux
+// REQUIRES: x86_64-target-arch
// REQUIRES: built-in-llvm-tree
#include "xray/xray_log_interface.h"
@@ -61,7 +61,7 @@ int main(int argc, char *argv[]) {
}
// We want to make sure that the order of the function log doesn't matter.
-// TRACE-DAG: - { type: 0, func-id: [[FID1:[0-9]+]], function: {{.*f1.*}}, cpu: {{.*}}, thread: [[THREAD1:[0-9]+]], kind: function-enter, tsc: {{[0-9]+}} }
-// TRACE-DAG: - { type: 0, func-id: [[FID2:[0-9]+]], function: {{.*f2.*}}, cpu: {{.*}}, thread: [[THREAD2:[0-9]+]], kind: function-enter, tsc: {{[0-9]+}} }
-// TRACE-DAG: - { type: 0, func-id: [[FID1]], function: {{.*f1.*}}, cpu: {{.*}}, thread: [[THREAD1]], kind: {{function-exit|function-tail-exit}}, tsc: {{[0-9]+}} }
-// TRACE-DAG: - { type: 0, func-id: [[FID2]], function: {{.*f2.*}}, cpu: {{.*}}, thread: [[THREAD2]], kind: {{function-exit|function-tail-exit}}, tsc: {{[0-9]+}} }
+// TRACE-DAG: - { type: 0, func-id: [[FID1:[0-9]+]], function: {{.*f1.*}}, cpu: {{.*}}, thread: [[THREAD1:[0-9]+]], process: [[PROCESS:[0-9]+]], kind: function-enter, tsc: {{[0-9]+}} }
+// TRACE-DAG: - { type: 0, func-id: [[FID2:[0-9]+]], function: {{.*f2.*}}, cpu: {{.*}}, thread: [[THREAD2:[0-9]+]], process: [[PROCESS]], kind: function-enter, tsc: {{[0-9]+}} }
+// TRACE-DAG: - { type: 0, func-id: [[FID1]], function: {{.*f1.*}}, cpu: {{.*}}, thread: [[THREAD1]], process: [[PROCESS]], kind: {{function-exit|function-tail-exit}}, tsc: {{[0-9]+}} }
+// TRACE-DAG: - { type: 0, func-id: [[FID2]], function: {{.*f2.*}}, cpu: {{.*}}, thread: [[THREAD2]], process: [[PROCESS]], kind: {{function-exit|function-tail-exit}}, tsc: {{[0-9]+}} }
diff --git a/test/xray/TestCases/Linux/fixedsize-logging.cc b/test/xray/TestCases/Posix/fixedsize-logging.cc
index a2a41ce60d6e..a2a41ce60d6e 100644
--- a/test/xray/TestCases/Linux/fixedsize-logging.cc
+++ b/test/xray/TestCases/Posix/fixedsize-logging.cc
diff --git a/test/xray/TestCases/Posix/fork_basic_logging.cc b/test/xray/TestCases/Posix/fork_basic_logging.cc
new file mode 100644
index 000000000000..5aefdec08016
--- /dev/null
+++ b/test/xray/TestCases/Posix/fork_basic_logging.cc
@@ -0,0 +1,100 @@
+// Check that when forking in basic logging mode, we get the different tids for child and parent
+// RUN: %clangxx_xray -g -std=c++11 %s -o %t
+// RUN: rm -f fork-basic-logging-test-*
+// RUN: XRAY_OPTIONS="patch_premain=true xray_logfile_base=fork-basic-logging-test- \
+// RUN: xray_mode=xray-basic verbosity=1 xray_naive_log_func_duration_threshold_us=0" \
+// RUN: %run %t 2>&1 | FileCheck %s
+// RUN: %llvm_xray convert --symbolize --output-format=yaml -instr_map=%t \
+// RUN: "`ls -S fork-basic-logging-test-* | head -1`" \
+// RUN: | FileCheck %s --check-prefix=TRACE
+
+// REQUIRES: x86_64-target-arch
+// REQUIRES: built-in-llvm-tree
+
+#include "xray/xray_log_interface.h"
+#include <stdio.h>
+#include <unistd.h>
+#include <stdint.h>
+#include <sys/syscall.h>
+
+//modified from sanitizer
+
+static uintptr_t syscall_gettid() {
+ uint64_t retval;
+ asm volatile("syscall" : "=a"(retval) : "a"(__NR_gettid) : "rcx", "r11",
+ "memory", "cc");
+ return retval;
+}
+
+/////////////
+
+static uint64_t parent_tid;
+
+[[clang::xray_always_instrument]]
+uint64_t __attribute__((noinline)) log_syscall_gettid()
+{
+ //don't optimize this function away
+ uint64_t tid = syscall_gettid();
+ printf("Logging tid %lu\n", tid);
+ return tid;
+}
+
+[[clang::xray_always_instrument, clang::xray_log_args(1)]]
+void __attribute__((noinline)) print_parent_tid(uint64_t tid)
+{
+ printf("Parent with tid %lu", tid);
+}
+
+[[clang::xray_always_instrument, clang::xray_log_args(1)]]
+void __attribute__((noinline)) print_child_tid(uint64_t tid)
+{
+ printf("Child with tid %lu", tid);
+}
+
+[[clang::xray_always_instrument]] void __attribute__((noinline)) print_parent_or_child()
+{
+ uint64_t tid = syscall_gettid();
+ if(tid == parent_tid)
+ {
+ print_parent_tid(tid);
+ }
+ else
+ {
+ print_child_tid(tid);
+ }
+}
+
+int main()
+{
+ parent_tid = log_syscall_gettid();
+ if(fork())
+ {
+ print_parent_or_child();
+ // CHECK-DAG: Parent with tid
+ }
+ else
+ {
+ print_parent_or_child();
+ // CHECK-DAG: Child with tid
+ }
+ return 0;
+}
+
+// Make sure we know which thread is the parent process
+// TRACE-DAG: - { type: 0, func-id: [[LSGT:[0-9]+]], function: {{.*log_syscall_gettid.*}}, cpu: {{.*}}, thread: [[THREAD1:[0-9]+]], process: [[PROCESS1:[0-9]+]], kind: function-enter, tsc: {{[0-9]+}} }
+
+// TRACE-DAG: - { type: 0, func-id: [[PPOC:[0-9]+]], function: {{.*print_parent_or_child.*}}, cpu: {{.*}}, thread: [[THREAD1]], process: [[PROCESS1]], kind: function-enter, tsc: {{[0-9]+}} }
+//
+// The parent will print its pid
+// TRACE-DAG: - { type: 0, func-id: [[PPTARG:[0-9]+]], function: {{.*print_parent_tid.*}}, args: [ [[THREAD1]] ], cpu: {{.*}}, thread: [[THREAD1]], process: [[PROCESS1]], kind: function-enter-arg, tsc: {{[0-9]+}} }
+// TRACE-DAG: - { type: 0, func-id: [[PPTARG]], function: {{.*print_parent_tid.*}}, cpu: {{.*}}, thread: [[THREAD1]], process: [[PROCESS1]], kind: function-exit, tsc: {{[0-9]+}} }
+//
+// TRACE-DAG - { type: 0, func-id: [[PPOC]], function: {{.*print_parent_or_child.*}}, cpu: {{.*}}, thread: [[THREAD1]], process: [[PROCESS1]], kind: function-{{exit|tail-exit}}, tsc: {{[0-9]+}} }
+
+// TRACE-DAG: - { type: 0, func-id: [[PPOC]], function: {{.*print_parent_or_child.*}}, cpu: {{.*}}, thread: [[THREAD2:[0-9]+]], process: [[PROCESS2:[0-9]+]], kind: function-enter, tsc: {{[0-9]+}} }
+//
+// The child will print its pid
+// TRACE-DAG: - { type: 0, func-id: [[PCTARG:[0-9]+]], function: {{.*print_child_tid.*}}, args: [ [[THREAD2]] ], cpu: {{.*}}, thread: [[THREAD2]], process: [[PROCESS2]], kind: function-enter-arg, tsc: {{[0-9]+}} }
+// TRACE-DAG: - { type: 0, func-id: [[PCTARG]], function: {{.*print_child_tid.*}}, cpu: {{.*}}, thread: [[THREAD2]], process: [[PROCESS2]], kind: function-exit, tsc: {{[0-9]+}} }
+//
+// TRACE-DAG: - { type: 0, func-id: [[PPOC]], function: {{.*print_parent_or_child.*}}, cpu: {{.*}}, thread: [[THREAD2]], process: [[PROCESS2]], kind: function-{{exit|tail-exit}}, tsc: {{[0-9]+}} }
diff --git a/test/xray/TestCases/Linux/func-id-utils.cc b/test/xray/TestCases/Posix/func-id-utils.cc
index 412753666019..412753666019 100644
--- a/test/xray/TestCases/Linux/func-id-utils.cc
+++ b/test/xray/TestCases/Posix/func-id-utils.cc
diff --git a/test/xray/TestCases/Linux/logging-modes.cc b/test/xray/TestCases/Posix/logging-modes.cc
index 22f6942b7595..f839ba5e5f50 100644
--- a/test/xray/TestCases/Linux/logging-modes.cc
+++ b/test/xray/TestCases/Posix/logging-modes.cc
@@ -1,6 +1,7 @@
// Check that we can install an implementation associated with a mode.
//
-// RUN: %clangxx_xray -std=c++11 %s -o %t
+// RUN: rm -f xray-log.logging-modes*
+// RUN: %clangxx_xray -std=c++11 %s -o %t -fxray-modes=none
// RUN: %run %t | FileCheck %s
//
// UNSUPPORTED: target-is-mips64,target-is-mips64el
@@ -9,6 +10,7 @@
#include "xray/xray_log_interface.h"
#include <cassert>
#include <cstdio>
+#include <string>
[[clang::xray_never_instrument]] void printing_handler(int32_t fid,
XRayEntryType) {
@@ -20,8 +22,29 @@
printing = false;
}
+[[clang::xray_never_instrument]] XRayBuffer next_buffer(XRayBuffer buffer) {
+ static const char data[10] = {};
+ static const XRayBuffer first_and_last{data, 10};
+ if (buffer.Data == nullptr)
+ return first_and_last;
+ if (buffer.Data == first_and_last.Data)
+ return XRayBuffer{nullptr, 0};
+ assert(false && "Invalid buffer provided.");
+}
+
+static constexpr char Options[] = "additional_flags";
+
[[clang::xray_never_instrument]] XRayLogInitStatus
-printing_init(size_t, size_t, void *, size_t) {
+printing_init(size_t BufferSize, size_t MaxBuffers, void *Config,
+ size_t ArgsSize) {
+ // We require that the printing init is called through the
+ // __xray_log_init_mode(...) implementation, and that the promised contract is
+ // enforced.
+ assert(BufferSize == 0);
+ assert(MaxBuffers == 0);
+ assert(Config != nullptr);
+ assert(ArgsSize == 0 || ArgsSize == sizeof(Options));
+ __xray_log_set_buffer_iterator(next_buffer);
return XRayLogInitStatus::XRAY_LOG_INITIALIZED;
}
@@ -30,29 +53,42 @@ printing_init(size_t, size_t, void *, size_t) {
}
[[clang::xray_never_instrument]] XRayLogFlushStatus printing_flush_log() {
+ __xray_log_remove_buffer_iterator();
return XRayLogFlushStatus::XRAY_LOG_FLUSHED;
}
[[clang::xray_always_instrument]] void callme() { std::printf("called me!\n"); }
-static bool unused = [] {
+static auto buffer_counter = 0;
+
+void process_buffer(const char *, XRayBuffer) { ++buffer_counter; }
+
+int main(int argc, char **argv) {
assert(__xray_log_register_mode("custom",
{printing_init, printing_finalize,
printing_handler, printing_flush_log}) ==
XRayLogRegisterStatus::XRAY_REGISTRATION_OK);
- return true;
-}();
-
-int main(int argc, char **argv) {
assert(__xray_log_select_mode("custom") ==
XRayLogRegisterStatus::XRAY_REGISTRATION_OK);
+ assert(__xray_log_get_current_mode() != nullptr);
+ std::string current_mode = __xray_log_get_current_mode();
+ assert(current_mode == "custom");
assert(__xray_patch() == XRayPatchingStatus::SUCCESS);
- assert(__xray_log_init(0, 0, nullptr, 0) ==
+ assert(__xray_log_init_mode("custom", "flags_config_here=true") ==
XRayLogInitStatus::XRAY_LOG_INITIALIZED);
+
+ // Also test that we can use the "binary" version of the
+ // __xray_log_niit_mode(...) API.
+ assert(__xray_log_init_mode_bin("custom", Options, sizeof(Options)) ==
+ XRayLogInitStatus::XRAY_LOG_INITIALIZED);
+
// CHECK: printing {{.*}}
callme(); // CHECK: called me!
// CHECK: printing {{.*}}
assert(__xray_log_finalize() == XRayLogInitStatus::XRAY_LOG_FINALIZED);
+ assert(__xray_log_process_buffers(process_buffer) ==
+ XRayLogFlushStatus::XRAY_LOG_FLUSHED);
+ assert(buffer_counter == 1);
assert(__xray_log_flushLog() == XRayLogFlushStatus::XRAY_LOG_FLUSHED);
assert(__xray_log_select_mode("not-found") ==
XRayLogRegisterStatus::XRAY_MODE_NOT_FOUND);
diff --git a/test/xray/TestCases/Linux/optional-inmemory-log.cc b/test/xray/TestCases/Posix/optional-inmemory-log.cc
index feaaa4124750..feaaa4124750 100644
--- a/test/xray/TestCases/Linux/optional-inmemory-log.cc
+++ b/test/xray/TestCases/Posix/optional-inmemory-log.cc
diff --git a/test/xray/TestCases/Linux/patching-unpatching.cc b/test/xray/TestCases/Posix/patching-unpatching.cc
index a7ea58f6dc69..a7ea58f6dc69 100644
--- a/test/xray/TestCases/Linux/patching-unpatching.cc
+++ b/test/xray/TestCases/Posix/patching-unpatching.cc
diff --git a/test/xray/TestCases/Linux/pic_test.cc b/test/xray/TestCases/Posix/pic_test.cc
index 4de1ad3d6da9..93e1a6a47d3c 100644
--- a/test/xray/TestCases/Linux/pic_test.cc
+++ b/test/xray/TestCases/Posix/pic_test.cc
@@ -2,12 +2,12 @@
// RUN: %clangxx_xray -fxray-instrument -std=c++11 -ffunction-sections \
// RUN: -fdata-sections -fpic -fpie -Wl,--gc-sections %s -o %t
-// RUN: rm pic-test-logging-* || true
+// RUN: rm -f pic-test-logging-*
// RUN: XRAY_OPTIONS="patch_premain=true verbosity=1 xray_naive_log=true \
// RUN: xray_logfile_base=pic-test-logging-" %run %t 2>&1 | FileCheck %s
// After all that, clean up the output xray log.
//
-// RUN: rm pic-test-logging-* || true
+// RUN: rm -f pic-test-logging-*
// UNSUPPORTED: target-is-mips64,target-is-mips64el
diff --git a/test/xray/TestCases/Posix/profiling-multi-threaded.cc b/test/xray/TestCases/Posix/profiling-multi-threaded.cc
new file mode 100644
index 000000000000..7ccad1bac1fd
--- /dev/null
+++ b/test/xray/TestCases/Posix/profiling-multi-threaded.cc
@@ -0,0 +1,57 @@
+// Check that we can get a profile from a single-threaded application, on
+// demand through the XRay logging implementation API.
+//
+// FIXME: Make -fxray-modes=xray-profiling part of the default?
+// RUN: %clangxx_xray -std=c++11 %s -o %t -fxray-modes=xray-profiling
+// RUN: rm -f xray-log.profiling-multi-*
+// RUN: XRAY_OPTIONS=verbosity=1 \
+// RUN: XRAY_PROFILING_OPTIONS=no_flush=1 %run %t
+// RUN: XRAY_OPTIONS=verbosity=1 %run %t
+// RUN: PROFILES=`ls xray-log.profiling-multi-* | wc -l`
+// RUN: [ $PROFILES -eq 1 ]
+// RUN: rm -f xray-log.profiling-multi-*
+//
+// REQUIRES: x86_64-target-arch
+// REQUIRES: built-in-llvm-tree
+
+#include "xray/xray_interface.h"
+#include "xray/xray_log_interface.h"
+#include <cassert>
+#include <cstdio>
+#include <string>
+#include <thread>
+
+[[clang::xray_always_instrument]] void f2() { return; }
+[[clang::xray_always_instrument]] void f1() { f2(); }
+[[clang::xray_always_instrument]] void f0() { f1(); }
+
+using namespace std;
+
+volatile int buffer_counter = 0;
+
+[[clang::xray_never_instrument]] void process_buffer(const char *, XRayBuffer) {
+ // FIXME: Actually assert the contents of the buffer.
+ ++buffer_counter;
+}
+
+[[clang::xray_always_instrument]] int main(int, char **) {
+ assert(__xray_log_select_mode("xray-profiling") ==
+ XRayLogRegisterStatus::XRAY_REGISTRATION_OK);
+ assert(__xray_log_get_current_mode() != nullptr);
+ std::string current_mode = __xray_log_get_current_mode();
+ assert(current_mode == "xray-profiling");
+ assert(__xray_patch() == XRayPatchingStatus::SUCCESS);
+ assert(__xray_log_init(0, 0, nullptr, 0) ==
+ XRayLogInitStatus::XRAY_LOG_INITIALIZED);
+ std::thread t0([] { f0(); });
+ std::thread t1([] { f0(); });
+ f0();
+ t0.join();
+ t1.join();
+ assert(__xray_log_finalize() == XRayLogInitStatus::XRAY_LOG_FINALIZED);
+ assert(__xray_log_process_buffers(process_buffer) ==
+ XRayLogFlushStatus::XRAY_LOG_FLUSHED);
+ // We're running three threds, so we expect three buffers.
+ assert(buffer_counter == 3);
+ assert(__xray_log_flushLog() == XRayLogFlushStatus::XRAY_LOG_FLUSHED);
+}
diff --git a/test/xray/TestCases/Posix/profiling-single-threaded.cc b/test/xray/TestCases/Posix/profiling-single-threaded.cc
new file mode 100644
index 000000000000..fd508b1acd14
--- /dev/null
+++ b/test/xray/TestCases/Posix/profiling-single-threaded.cc
@@ -0,0 +1,65 @@
+// Check that we can get a profile from a single-threaded application, on
+// demand through the XRay logging implementation API.
+//
+// FIXME: Make -fxray-modes=xray-profiling part of the default?
+// RUN: %clangxx_xray -std=c++11 %s -o %t -fxray-modes=xray-profiling
+// RUN: rm -f xray-log.profiling-single-*
+// RUN: XRAY_OPTIONS=verbosity=1 \
+// RUN: XRAY_PROFILING_OPTIONS=no_flush=true %run %t
+// RUN: XRAY_OPTIONS=verbosity=1 %run %t
+// RUN: PROFILES=`ls xray-log.profiling-single-* | wc -l`
+// RUN: [ $PROFILES -eq 2 ]
+// RUN: rm -f xray-log.profiling-single-*
+//
+// REQUIRES: x86_64-target-arch
+// REQUIRES: built-in-llvm-tree
+
+#include "xray/xray_interface.h"
+#include "xray/xray_log_interface.h"
+#include <cassert>
+#include <cstdio>
+#include <string>
+
+[[clang::xray_always_instrument]] void f2() { return; }
+[[clang::xray_always_instrument]] void f1() { f2(); }
+[[clang::xray_always_instrument]] void f0() { f1(); }
+
+using namespace std;
+
+volatile int buffer_counter = 0;
+
+[[clang::xray_never_instrument]] void process_buffer(const char *, XRayBuffer) {
+ // FIXME: Actually assert the contents of the buffer.
+ ++buffer_counter;
+}
+
+[[clang::xray_always_instrument]] int main(int, char **) {
+ assert(__xray_log_select_mode("xray-profiling") ==
+ XRayLogRegisterStatus::XRAY_REGISTRATION_OK);
+ assert(__xray_log_get_current_mode() != nullptr);
+ std::string current_mode = __xray_log_get_current_mode();
+ assert(current_mode == "xray-profiling");
+ assert(__xray_patch() == XRayPatchingStatus::SUCCESS);
+ assert(__xray_log_init_mode("xray-profiling", "") ==
+ XRayLogInitStatus::XRAY_LOG_INITIALIZED);
+ f0();
+ assert(__xray_log_finalize() == XRayLogInitStatus::XRAY_LOG_FINALIZED);
+ f0();
+ assert(__xray_log_process_buffers(process_buffer) ==
+ XRayLogFlushStatus::XRAY_LOG_FLUSHED);
+ assert(buffer_counter == 1);
+ assert(__xray_log_flushLog() == XRayLogFlushStatus::XRAY_LOG_FLUSHED);
+
+ // Let's reset the counter.
+ buffer_counter = 0;
+
+ assert(__xray_log_init_mode("xray-profiling", "") ==
+ XRayLogInitStatus::XRAY_LOG_INITIALIZED);
+ f0();
+ assert(__xray_log_finalize() == XRayLogInitStatus::XRAY_LOG_FINALIZED);
+ f0();
+ assert(__xray_log_process_buffers(process_buffer) ==
+ XRayLogFlushStatus::XRAY_LOG_FLUSHED);
+ assert(buffer_counter == 1);
+ assert(__xray_log_flushLog() == XRayLogFlushStatus::XRAY_LOG_FLUSHED);
+}
diff --git a/test/xray/TestCases/Linux/quiet-start.cc b/test/xray/TestCases/Posix/quiet-start.cc
index e26fa63aa5ba..00d5af6609dd 100644
--- a/test/xray/TestCases/Linux/quiet-start.cc
+++ b/test/xray/TestCases/Posix/quiet-start.cc
@@ -10,7 +10,7 @@
//
// FIXME: Understand how to make this work on other platforms
// REQUIRES: built-in-llvm-tree
-// REQUIRES: x86_64-linux
+// REQUIRES: x86_64-target-arch
#include <iostream>
using namespace std;
diff --git a/test/xray/lit.cfg b/test/xray/lit.cfg
index d5e40975da56..0dc2108ba187 100644
--- a/test/xray/lit.cfg
+++ b/test/xray/lit.cfg
@@ -20,6 +20,11 @@ def build_invocation(compile_flags):
llvm_xray = os.path.join(config.llvm_tools_dir, 'llvm-xray')
# Setup substitutions.
+if config.host_os == "Linux":
+ libdl_flag = "-ldl"
+else:
+ libdl_flag = ""
+
config.substitutions.append(
('%clang ', build_invocation([config.target_cflags])))
config.substitutions.append(
@@ -33,14 +38,14 @@ config.substitutions.append(
('%llvm_xray', llvm_xray))
config.substitutions.append(
('%xraylib',
- ('-lm -lpthread -ldl -lrt -L%s '
- '-Wl,-whole-archive -lclang_rt.xray-%s -Wl,-no-whole-archive')
- % (config.compiler_rt_libdir, config.host_arch)))
+ ('-lm -lpthread %s -lrt -L%s '
+ '-Wl,-whole-archive -lclang_rt.xray%s -Wl,-no-whole-archive')
+ % (libdl_flag, config.compiler_rt_libdir, config.target_suffix)))
# Default test suffixes.
config.suffixes = ['.c', '.cc', '.cpp']
-if config.host_os not in ['Linux']:
+if config.host_os not in ['FreeBSD', 'Linux', 'NetBSD', 'OpenBSD']:
config.unsupported = True
elif '64' not in config.host_arch:
if 'arm' in config.host_arch: