1*4b4437c0SVitaly Buka // RUN: %clangxx_asan -fexceptions -O %s -o %t && %env_asan_opts=detect_stack_use_after_return=0 %run %t
2673dc3d4SNico Weber //
3673dc3d4SNico Weber // Test __sanitizer_annotate_contiguous_container.
4673dc3d4SNico Weber
5673dc3d4SNico Weber #include <stdlib.h>
6673dc3d4SNico Weber #include <stdio.h>
7673dc3d4SNico Weber #include <string.h>
8673dc3d4SNico Weber #include <assert.h>
9673dc3d4SNico Weber #include <sanitizer/asan_interface.h>
10673dc3d4SNico Weber
TestContainer(size_t capacity)11673dc3d4SNico Weber void TestContainer(size_t capacity) {
12673dc3d4SNico Weber char *beg = new char[capacity];
13673dc3d4SNico Weber char *end = beg + capacity;
14673dc3d4SNico Weber char *mid = beg + capacity;
15673dc3d4SNico Weber char *old_mid = 0;
16673dc3d4SNico Weber
17673dc3d4SNico Weber for (int i = 0; i < 10000; i++) {
18673dc3d4SNico Weber size_t size = rand() % (capacity + 1);
19673dc3d4SNico Weber assert(size <= capacity);
20673dc3d4SNico Weber old_mid = mid;
21673dc3d4SNico Weber mid = beg + size;
22673dc3d4SNico Weber __sanitizer_annotate_contiguous_container(beg, end, old_mid, mid);
23673dc3d4SNico Weber
24673dc3d4SNico Weber for (size_t idx = 0; idx < size; idx++)
25673dc3d4SNico Weber assert(!__asan_address_is_poisoned(beg + idx));
26673dc3d4SNico Weber for (size_t idx = size; idx < capacity; idx++)
27673dc3d4SNico Weber assert(__asan_address_is_poisoned(beg + idx));
28673dc3d4SNico Weber assert(__sanitizer_verify_contiguous_container(beg, mid, end));
29673dc3d4SNico Weber assert(NULL ==
30673dc3d4SNico Weber __sanitizer_contiguous_container_find_bad_address(beg, mid, end));
31673dc3d4SNico Weber if (mid != beg) {
32673dc3d4SNico Weber assert(!__sanitizer_verify_contiguous_container(beg, mid - 1, end));
33673dc3d4SNico Weber assert(mid - 1 == __sanitizer_contiguous_container_find_bad_address(
34673dc3d4SNico Weber beg, mid - 1, end));
35673dc3d4SNico Weber }
36673dc3d4SNico Weber if (mid != end) {
37673dc3d4SNico Weber assert(!__sanitizer_verify_contiguous_container(beg, mid + 1, end));
38673dc3d4SNico Weber assert(mid == __sanitizer_contiguous_container_find_bad_address(
39673dc3d4SNico Weber beg, mid + 1, end));
40673dc3d4SNico Weber }
41673dc3d4SNico Weber }
42673dc3d4SNico Weber
43a1e7e401SKazuaki Ishizaki // Don't forget to unpoison the whole thing before destroying/reallocating.
44673dc3d4SNico Weber __sanitizer_annotate_contiguous_container(beg, end, mid, end);
45673dc3d4SNico Weber for (size_t idx = 0; idx < capacity; idx++)
46673dc3d4SNico Weber assert(!__asan_address_is_poisoned(beg + idx));
47673dc3d4SNico Weber delete[] beg;
48673dc3d4SNico Weber }
49673dc3d4SNico Weber
50673dc3d4SNico Weber __attribute__((noinline))
Throw()51673dc3d4SNico Weber void Throw() { throw 1; }
52673dc3d4SNico Weber
53673dc3d4SNico Weber __attribute__((noinline))
ThrowAndCatch()54673dc3d4SNico Weber void ThrowAndCatch() {
55673dc3d4SNico Weber try {
56673dc3d4SNico Weber Throw();
57673dc3d4SNico Weber } catch(...) {
58673dc3d4SNico Weber }
59673dc3d4SNico Weber }
60673dc3d4SNico Weber
TestThrow()61673dc3d4SNico Weber void TestThrow() {
62673dc3d4SNico Weber char x[32];
63673dc3d4SNico Weber __sanitizer_annotate_contiguous_container(x, x + 32, x + 32, x + 14);
64673dc3d4SNico Weber assert(!__asan_address_is_poisoned(x + 13));
65673dc3d4SNico Weber assert(__asan_address_is_poisoned(x + 14));
66673dc3d4SNico Weber ThrowAndCatch();
67673dc3d4SNico Weber assert(!__asan_address_is_poisoned(x + 13));
68673dc3d4SNico Weber assert(!__asan_address_is_poisoned(x + 14));
69673dc3d4SNico Weber __sanitizer_annotate_contiguous_container(x, x + 32, x + 14, x + 32);
70673dc3d4SNico Weber assert(!__asan_address_is_poisoned(x + 13));
71673dc3d4SNico Weber assert(!__asan_address_is_poisoned(x + 14));
72673dc3d4SNico Weber }
73673dc3d4SNico Weber
main(int argc,char ** argv)74673dc3d4SNico Weber int main(int argc, char **argv) {
75673dc3d4SNico Weber int n = argc == 1 ? 128 : atoi(argv[1]);
76673dc3d4SNico Weber for (int i = 0; i <= n; i++)
77673dc3d4SNico Weber TestContainer(i);
78673dc3d4SNico Weber TestThrow();
79673dc3d4SNico Weber }
80