1// RUN: %clangxx_asan -O %s -o %t && %run %t 2// 3// Test __sanitizer_annotate_contiguous_container. 4 5#include <stdlib.h> 6#include <stdio.h> 7#include <string.h> 8#include <assert.h> 9#include <sanitizer/asan_interface.h> 10 11void TestContainer(size_t capacity) { 12 char *beg = new char[capacity]; 13 char *end = beg + capacity; 14 char *mid = beg + capacity; 15 char *old_mid = 0; 16 17 for (int i = 0; i < 10000; i++) { 18 size_t size = rand() % (capacity + 1); 19 assert(size <= capacity); 20 old_mid = mid; 21 mid = beg + size; 22 __sanitizer_annotate_contiguous_container(beg, end, old_mid, mid); 23 24 for (size_t idx = 0; idx < size; idx++) 25 assert(!__asan_address_is_poisoned(beg + idx)); 26 for (size_t idx = size; idx < capacity; idx++) 27 assert(__asan_address_is_poisoned(beg + idx)); 28 assert(__sanitizer_verify_contiguous_container(beg, mid, end)); 29 if (mid != beg) 30 assert(!__sanitizer_verify_contiguous_container(beg, mid - 1, end)); 31 if (mid != end) 32 assert(!__sanitizer_verify_contiguous_container(beg, mid + 1, end)); 33 } 34 35 // Don't forget to unpoison the whole thing before destroing/reallocating. 36 __sanitizer_annotate_contiguous_container(beg, end, mid, end); 37 for (size_t idx = 0; idx < capacity; idx++) 38 assert(!__asan_address_is_poisoned(beg + idx)); 39 delete[] beg; 40} 41 42__attribute__((noinline)) 43void Throw() { throw 1; } 44 45__attribute__((noinline)) 46void ThrowAndCatch() { 47 try { 48 Throw(); 49 } catch(...) { 50 } 51} 52 53void TestThrow() { 54 char x[32]; 55 __sanitizer_annotate_contiguous_container(x, x + 32, x + 32, x + 14); 56 assert(!__asan_address_is_poisoned(x + 13)); 57 assert(__asan_address_is_poisoned(x + 14)); 58 ThrowAndCatch(); 59 assert(!__asan_address_is_poisoned(x + 13)); 60 // FIXME: invert the assertion below once we fix 61 // https://code.google.com/p/address-sanitizer/issues/detail?id=258 62 // This assertion works only w/o UAR. 63 if (!__asan_get_current_fake_stack()) 64 assert(!__asan_address_is_poisoned(x + 14)); 65 __sanitizer_annotate_contiguous_container(x, x + 32, x + 14, x + 32); 66 assert(!__asan_address_is_poisoned(x + 13)); 67 assert(!__asan_address_is_poisoned(x + 14)); 68} 69 70int main(int argc, char **argv) { 71 int n = argc == 1 ? 128 : atoi(argv[1]); 72 for (int i = 0; i <= n; i++) 73 TestContainer(i); 74 TestThrow(); 75} 76