]>
Commit | Line | Data |
---|---|---|
92a42be0 | 1 | // RUN: %clangxx_asan -fexceptions -O %s -o %t && %run %t |
1a4d82fc JJ |
2 | // |
3 | // Test __sanitizer_annotate_contiguous_container. | |
4 | ||
5 | #include <stdlib.h> | |
6 | #include <stdio.h> | |
7 | #include <string.h> | |
8 | #include <assert.h> | |
92a42be0 | 9 | #include <sanitizer/asan_interface.h> |
1a4d82fc JJ |
10 | |
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)); | |
92a42be0 SL |
28 | assert(__sanitizer_verify_contiguous_container(beg, mid, end)); |
29 | assert(NULL == | |
30 | __sanitizer_contiguous_container_find_bad_address(beg, mid, end)); | |
31 | if (mid != beg) { | |
32 | assert(!__sanitizer_verify_contiguous_container(beg, mid - 1, end)); | |
33 | assert(mid - 1 == __sanitizer_contiguous_container_find_bad_address( | |
34 | beg, mid - 1, end)); | |
35 | } | |
36 | if (mid != end) { | |
37 | assert(!__sanitizer_verify_contiguous_container(beg, mid + 1, end)); | |
38 | assert(mid == __sanitizer_contiguous_container_find_bad_address( | |
39 | beg, mid + 1, end)); | |
40 | } | |
1a4d82fc JJ |
41 | } |
42 | ||
43 | // Don't forget to unpoison the whole thing before destroing/reallocating. | |
44 | __sanitizer_annotate_contiguous_container(beg, end, mid, end); | |
45 | for (size_t idx = 0; idx < capacity; idx++) | |
46 | assert(!__asan_address_is_poisoned(beg + idx)); | |
47 | delete[] beg; | |
48 | } | |
49 | ||
50 | __attribute__((noinline)) | |
51 | void Throw() { throw 1; } | |
52 | ||
53 | __attribute__((noinline)) | |
54 | void ThrowAndCatch() { | |
55 | try { | |
56 | Throw(); | |
57 | } catch(...) { | |
58 | } | |
59 | } | |
60 | ||
61 | void TestThrow() { | |
62 | char x[32]; | |
63 | __sanitizer_annotate_contiguous_container(x, x + 32, x + 32, x + 14); | |
64 | assert(!__asan_address_is_poisoned(x + 13)); | |
65 | assert(__asan_address_is_poisoned(x + 14)); | |
66 | ThrowAndCatch(); | |
67 | assert(!__asan_address_is_poisoned(x + 13)); | |
68 | // FIXME: invert the assertion below once we fix | |
69 | // https://code.google.com/p/address-sanitizer/issues/detail?id=258 | |
92a42be0 SL |
70 | // This assertion works only w/o UAR. |
71 | if (!__asan_get_current_fake_stack()) | |
72 | assert(!__asan_address_is_poisoned(x + 14)); | |
1a4d82fc JJ |
73 | __sanitizer_annotate_contiguous_container(x, x + 32, x + 14, x + 32); |
74 | assert(!__asan_address_is_poisoned(x + 13)); | |
75 | assert(!__asan_address_is_poisoned(x + 14)); | |
76 | } | |
77 | ||
78 | int main(int argc, char **argv) { | |
79 | int n = argc == 1 ? 128 : atoi(argv[1]); | |
80 | for (int i = 0; i <= n; i++) | |
81 | TestContainer(i); | |
82 | TestThrow(); | |
83 | } |