| // Test __sanitizer_reset_coverage(). |
| |
| // RUN: %clangxx_asan -fsanitize-coverage=func %s -o %t |
| // RUN: %env_asan_opts=coverage=1 %run %t |
| |
| // https://github.com/google/sanitizers/issues/618 |
| // UNSUPPORTED: android |
| |
| #include <sanitizer/coverage_interface.h> |
| #include <stdio.h> |
| #include <assert.h> |
| static volatile int sink; |
| __attribute__((noinline)) void bar() { sink = 2; } |
| __attribute__((noinline)) void foo() { sink = 1; } |
| |
| // In MSVC 2015, printf is an inline function, which causes this test to fail as |
| // it introduces an extra coverage point. Define away printf on that platform to |
| // avoid the issue. |
| #if _MSC_VER >= 1900 |
| # define printf(arg, ...) |
| #endif |
| |
| #define GET_AND_PRINT_COVERAGE() \ |
| bitset = 0; \ |
| for (size_t i = 0; i < n_guards; i++) \ |
| if (guards[i]) bitset |= 1U << i; \ |
| printf("line %d: bitset %zd total: %zd\n", __LINE__, bitset, \ |
| __sanitizer_get_total_unique_coverage()); |
| |
| #define IS_POWER_OF_TWO(a) ((a & ((a) - 1)) == 0) |
| |
| int main() { |
| size_t *guards = 0; |
| size_t bitset; |
| size_t n_guards = __sanitizer_get_coverage_guards(&guards); |
| |
| GET_AND_PRINT_COVERAGE(); |
| size_t main_bit = bitset; |
| assert(IS_POWER_OF_TWO(main_bit)); |
| |
| foo(); |
| GET_AND_PRINT_COVERAGE(); |
| size_t foo_bit = bitset & ~main_bit; |
| assert(IS_POWER_OF_TWO(foo_bit)); |
| |
| bar(); |
| GET_AND_PRINT_COVERAGE(); |
| size_t bar_bit = bitset & ~(main_bit | foo_bit); |
| assert(IS_POWER_OF_TWO(bar_bit)); |
| |
| __sanitizer_reset_coverage(); |
| assert(__sanitizer_get_total_unique_coverage() == 0); |
| GET_AND_PRINT_COVERAGE(); |
| assert(bitset == 0); |
| |
| foo(); |
| GET_AND_PRINT_COVERAGE(); |
| assert(bitset == foo_bit); |
| |
| bar(); |
| GET_AND_PRINT_COVERAGE(); |
| assert(bitset == (foo_bit | bar_bit)); |
| } |