coverage-reset.cc revision cdce50bda3603770cc4ef80cbb613c78b8e47a17
1// Test __sanitizer_reset_coverage().
2
3// RUN: %clangxx_asan -fsanitize-coverage=func %s -o %t
4// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:coverage=1 %run %t
5
6#include <sanitizer/coverage_interface.h>
7#include <stdio.h>
8#include <assert.h>
9static volatile int sink;
10__attribute__((noinline)) void bar() { sink = 2; }
11__attribute__((noinline)) void foo() { sink = 1; }
12
13#define GET_AND_PRINT_COVERAGE()                                       \
14  bitset = 0;                                                  \
15  for (size_t i = 0; i < n_guards; i++)                        \
16    if (guards[i]) bitset |= 1U << i;                          \
17  printf("line %d: bitset %zd total: %zd\n", __LINE__, bitset, \
18         __sanitizer_get_total_unique_coverage());
19
20#define IS_POWER_OF_TWO(a) ((a & ((a) - 1)) == 0)
21
22int main() {
23  size_t *guards = 0;
24  size_t bitset;
25  size_t n_guards = __sanitizer_get_coverage_guards(&guards);
26
27  GET_AND_PRINT_COVERAGE();
28  size_t main_bit = bitset;
29  assert(IS_POWER_OF_TWO(main_bit));
30
31  foo();
32  GET_AND_PRINT_COVERAGE();
33  size_t foo_bit = bitset & ~main_bit;
34  assert(IS_POWER_OF_TWO(foo_bit));
35
36  bar();
37  GET_AND_PRINT_COVERAGE();
38  size_t bar_bit = bitset & ~(main_bit | foo_bit);
39  assert(IS_POWER_OF_TWO(bar_bit));
40
41  __sanitizer_reset_coverage();
42  GET_AND_PRINT_COVERAGE();
43  assert(bitset == 0);
44
45  foo();
46  GET_AND_PRINT_COVERAGE();
47  assert(bitset == foo_bit);
48
49  bar();
50  GET_AND_PRINT_COVERAGE();
51  assert(bitset == (foo_bit | bar_bit));
52}
53