xref: /llvm-project/compiler-rt/test/asan/TestCases/Linux/malloc-in-qsort.cpp (revision be366041fa652a53ad51b60dfa127214b6dbf529)
1673dc3d4SNico Weber // RUN: %clangxx_asan -O2 %s -o %t
2673dc3d4SNico Weber // RUN: %env_asan_opts=fast_unwind_on_malloc=1 not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-FAST
3673dc3d4SNico Weber // RUN: %env_asan_opts=fast_unwind_on_malloc=0 not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-SLOW
4673dc3d4SNico Weber 
5673dc3d4SNico Weber // Test how well we unwind in presence of qsort in the stack
6673dc3d4SNico Weber // (i.e. if we can unwind through a function compiled w/o frame pointers).
7673dc3d4SNico Weber // https://code.google.com/p/address-sanitizer/issues/detail?id=137
8673dc3d4SNico Weber 
9673dc3d4SNico Weber // Fast unwinder is only available on x86_64 and i386.
10673dc3d4SNico Weber // REQUIRES: x86-target-arch
11673dc3d4SNico Weber 
12673dc3d4SNico Weber // REQUIRES: compiler-rt-optimized
13673dc3d4SNico Weber 
14673dc3d4SNico Weber #include <stdlib.h>
15673dc3d4SNico Weber #include <stdio.h>
16673dc3d4SNico Weber 
17673dc3d4SNico Weber int *GlobalPtr;
18673dc3d4SNico Weber 
19673dc3d4SNico Weber extern "C" {
QsortCallback(const void * a,const void * b)20673dc3d4SNico Weber int QsortCallback(const void *a, const void *b) {
21673dc3d4SNico Weber   char *x = (char*)a;
22673dc3d4SNico Weber   char *y = (char*)b;
23673dc3d4SNico Weber   printf("Calling QsortCallback\n");
24673dc3d4SNico Weber   GlobalPtr = new int[10];
25673dc3d4SNico Weber   return (int)*x - (int)*y;
26673dc3d4SNico Weber }
27673dc3d4SNico Weber 
28673dc3d4SNico Weber __attribute__((noinline))
MyQsort(char * a,size_t size)29673dc3d4SNico Weber void MyQsort(char *a, size_t size) {
30673dc3d4SNico Weber   printf("Calling qsort\n");
31673dc3d4SNico Weber   qsort(a, size, sizeof(char), QsortCallback);
32673dc3d4SNico Weber   printf("Done\n");  // Avoid tail call.
33673dc3d4SNico Weber }
34673dc3d4SNico Weber }  // extern "C"
35673dc3d4SNico Weber 
main()36673dc3d4SNico Weber int main() {
37673dc3d4SNico Weber   char a[2] = {1, 2};
38673dc3d4SNico Weber   MyQsort(a, 2);
39673dc3d4SNico Weber   return GlobalPtr[10];
40673dc3d4SNico Weber }
41673dc3d4SNico Weber 
42673dc3d4SNico Weber // Fast unwind may not unwind through qsort.
43673dc3d4SNico Weber // CHECK-FAST: ERROR: AddressSanitizer: heap-buffer-overflow
44*be366041SFlorian Mayer // CHECK-FAST: is located 0 bytes after
45673dc3d4SNico Weber // CHECK-FAST: #0{{.*}}operator new
46673dc3d4SNico Weber // CHECK-FAST-NEXT: #1{{.*}}QsortCallback
47673dc3d4SNico Weber 
48673dc3d4SNico Weber // CHECK-SLOW: ERROR: AddressSanitizer: heap-buffer-overflow
49*be366041SFlorian Mayer // CHECK-SLOW: is located 0 bytes after
50673dc3d4SNico Weber // CHECK-SLOW: #0{{.*}}operator new
51673dc3d4SNico Weber // CHECK-SLOW-NEXT: #1{{.*}}QsortCallback
52673dc3d4SNico Weber // CHECK-SLOW: #{{.*}}MyQsort
53673dc3d4SNico Weber // CHECK-SLOW-NEXT: #{{.*}}main
54