1// Test __sanitizer_coverage_pc_buffer().
2
3// RUN: %clangxx_asan -fsanitize-coverage=edge %s -o %t && %run %t
4
5// UNSUPPORTED: android
6
7#include <assert.h>
8#include <sanitizer/coverage_interface.h>
9#include <stdio.h>
10
11static volatile int sink;
12__attribute__((noinline)) void bar() { sink = 2; }
13__attribute__((noinline)) void foo() { sink = 1; }
14
15void assertNotZeroPcs(uintptr_t *buf, uintptr_t size) {
16  assert(buf);
17  for (uintptr_t i = 0; i < size; ++i)
18    assert(buf[i]);
19}
20
21int main() {
22  {
23    uintptr_t *buf = NULL;
24    uintptr_t sz = __sanitizer_get_coverage_pc_buffer(&buf);
25    assertNotZeroPcs(buf, sz);
26    assert(sz);
27  }
28
29  {
30    uintptr_t *buf = NULL;
31    uintptr_t sz = __sanitizer_get_coverage_pc_buffer(&buf);
32    // call functions for the first time.
33    foo();
34    bar();
35    uintptr_t *buf1 = NULL;
36    uintptr_t sz1 = __sanitizer_get_coverage_pc_buffer(&buf1);
37    assertNotZeroPcs(buf1, sz1);
38    assert(buf1 == buf);
39    assert(sz1 > sz);
40  }
41
42  {
43    uintptr_t *buf = NULL;
44    uintptr_t sz = __sanitizer_get_coverage_pc_buffer(&buf);
45    // second call shouldn't increase coverage.
46    bar();
47    uintptr_t *buf1 = NULL;
48    uintptr_t sz1 = __sanitizer_get_coverage_pc_buffer(&buf1);
49    assertNotZeroPcs(buf1, sz1);
50    assert(buf1 == buf);
51    assert(sz1 == sz);
52  }
53
54  {
55    uintptr_t *buf = NULL;
56    uintptr_t sz = __sanitizer_get_coverage_pc_buffer(&buf);
57    // reset coverage to 0.
58    __sanitizer_reset_coverage();
59    uintptr_t *buf1 = NULL;
60    uintptr_t sz1 = __sanitizer_get_coverage_pc_buffer(&buf1);
61    assertNotZeroPcs(buf1, sz1);
62    assert(buf1 == buf);
63    assert(sz1 < sz);
64  }
65}
66