// RUN: %clangxx_asan -fexceptions -O %s -o %t && %run %t // // Test __sanitizer_annotate_contiguous_container. #include <stdlib.h> #include <stdio.h> #include <string.h> #include <assert.h> #include <sanitizer/asan_interface.h> void TestContainer(size_t capacity) { char *beg = new char[capacity]; char *end = beg + capacity; char *mid = beg + capacity; char *old_mid = 0; for (int i = 0; i < 10000; i++) { size_t size = rand() % (capacity + 1); assert(size <= capacity); old_mid = mid; mid = beg + size; __sanitizer_annotate_contiguous_container(beg, end, old_mid, mid); for (size_t idx = 0; idx < size; idx++) assert(!__asan_address_is_poisoned(beg + idx)); for (size_t idx = size; idx < capacity; idx++) assert(__asan_address_is_poisoned(beg + idx)); assert(__sanitizer_verify_contiguous_container(beg, mid, end)); assert(NULL == __sanitizer_contiguous_container_find_bad_address(beg, mid, end)); if (mid != beg) { assert(!__sanitizer_verify_contiguous_container(beg, mid - 1, end)); assert(mid - 1 == __sanitizer_contiguous_container_find_bad_address( beg, mid - 1, end)); } if (mid != end) { assert(!__sanitizer_verify_contiguous_container(beg, mid + 1, end)); assert(mid == __sanitizer_contiguous_container_find_bad_address( beg, mid + 1, end)); } } // Don't forget to unpoison the whole thing before destroing/reallocating. __sanitizer_annotate_contiguous_container(beg, end, mid, end); for (size_t idx = 0; idx < capacity; idx++) assert(!__asan_address_is_poisoned(beg + idx)); delete[] beg; } __attribute__((noinline)) void Throw() { throw 1; } __attribute__((noinline)) void ThrowAndCatch() { try { Throw(); } catch(...) { } } void TestThrow() { char x[32]; __sanitizer_annotate_contiguous_container(x, x + 32, x + 32, x + 14); assert(!__asan_address_is_poisoned(x + 13)); assert(__asan_address_is_poisoned(x + 14)); ThrowAndCatch(); assert(!__asan_address_is_poisoned(x + 13)); // FIXME: invert the assertion below once we fix // https://code.google.com/p/address-sanitizer/issues/detail?id=258 // This assertion works only w/o UAR. if (!__asan_get_current_fake_stack()) assert(!__asan_address_is_poisoned(x + 14)); __sanitizer_annotate_contiguous_container(x, x + 32, x + 14, x + 32); assert(!__asan_address_is_poisoned(x + 13)); assert(!__asan_address_is_poisoned(x + 14)); } int main(int argc, char **argv) { int n = argc == 1 ? 128 : atoi(argv[1]); for (int i = 0; i <= n; i++) TestContainer(i); TestThrow(); }