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
TestContainer(size_t capacity)11 void 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))
Throw()43 void Throw() { throw 1; }
44
45 __attribute__((noinline))
ThrowAndCatch()46 void ThrowAndCatch() {
47 try {
48 Throw();
49 } catch(...) {
50 }
51 }
52
TestThrow()53 void 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 assert(!__asan_address_is_poisoned(x + 14));
63 __sanitizer_annotate_contiguous_container(x, x + 32, x + 14, x + 32);
64 assert(!__asan_address_is_poisoned(x + 13));
65 assert(!__asan_address_is_poisoned(x + 14));
66 }
67
main(int argc,char ** argv)68 int main(int argc, char **argv) {
69 int n = argc == 1 ? 128 : atoi(argv[1]);
70 for (int i = 0; i <= n; i++)
71 TestContainer(i);
72 TestThrow();
73 }
74