| 1 | // RUN: %clangxx_asan -O0 %s -o %t -mllvm -asan-detect-invalid-pointer-pair |
| 2 | |
| 3 | // RUN: %env_asan_opts=detect_invalid_pointer_pairs=1 %run %t k 2>&1 | FileCheck %s -check-prefix=OK -allow-empty |
| 4 | // RUN: %env_asan_opts=detect_invalid_pointer_pairs=1 not %run %t g 2>&1 | FileCheck %s -check-prefix=CMP -check-prefix=ALL-ERRORS |
| 5 | // RUN: %env_asan_opts=detect_invalid_pointer_pairs=1 not %run %t s 2>&1 | FileCheck %s -check-prefix=SUB -check-prefix=ALL-ERRORS |
| 6 | // RUN: %env_asan_opts=detect_invalid_pointer_pairs=1 not %run %t f 2>&1 | FileCheck %s -check-prefix=FREE -check-prefix=ALL-ERRORS |
| 7 | // XFAIL: msvc |
| 8 | #include <assert.h> |
| 9 | #include <stdlib.h> |
| 10 | |
| 11 | int f(char c, char *p, char *q) { |
| 12 | // ALL-ERRORS: ERROR: AddressSanitizer: invalid-pointer-pair |
| 13 | // [[PTR1:0x[0-9a-f]+]] [[PTR2:0x[0-9a-f]+]] |
| 14 | switch (c) { |
| 15 | case 'g': |
| 16 | // CMP: #{{[0-9]+ .*}} in f({{char, *char *\*, *char *\*}}) {{.*}}invalid-pointer-pairs.cpp:[[@LINE+1]] |
| 17 | return p > q; |
| 18 | case 's': |
| 19 | // SUB: #{{[0-9]+ .*}} in f({{char, *char *\*, *char *\*}}) {{.*}}invalid-pointer-pairs.cpp:[[@LINE+1]] |
| 20 | return p - q; |
| 21 | case 'k': { |
| 22 | // OK-NOT: ERROR |
| 23 | char *p2 = p + 20; |
| 24 | return p > p2; |
| 25 | } |
| 26 | case 'f': { |
| 27 | char *p3 = p + 20; |
| 28 | free(ptr: p); |
| 29 | // FREE: #{{[0-9]+ .*}} in f({{char, *char *\*, *char *\*}}) {{.*}}invalid-pointer-pairs.cpp:[[@LINE+2]] |
| 30 | // FREE: freed by thread |
| 31 | return p < p3; |
| 32 | } |
| 33 | } |
| 34 | assert(0); |
| 35 | } |
| 36 | |
| 37 | int main(int argc, char **argv) { |
| 38 | char *p = (char *)malloc(size: 42); |
| 39 | char *q = (char *)malloc(size: 42); |
| 40 | assert(argc >= 2); |
| 41 | f(c: argv[1][0], p, q); |
| 42 | free(ptr: p); |
| 43 | free(ptr: q); |
| 44 | } |
| 45 | |