1 // RUN: %clangxx -std=c++11 -frtti -fsanitize=vptr -g %s -O3 -o %t
2 // RUN: %run %t &> %t.log
3 // RUN: cat %t.log | not count 0 && FileCheck --input-file %t.log %s || cat %t.log | count 0
4
5 // REQUIRES: cxxabi
6
7 #include <sys/mman.h>
8 #include <unistd.h>
9
10 class Base {
11 public:
12 int i;
print()13 virtual void print() {}
14 };
15
16 class Derived : public Base {
17 public:
print()18 void print() {}
19 };
20
21
main()22 int main() {
23 int page_size = getpagesize();
24
25 void *non_accessible = mmap(nullptr, page_size * 2, PROT_NONE,
26 MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
27
28 if (non_accessible == MAP_FAILED)
29 return 0;
30
31 void *accessible = mmap((char*)non_accessible + page_size, page_size,
32 PROT_READ | PROT_WRITE,
33 MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
34 if (accessible == MAP_FAILED)
35 return 0;
36
37 char *c = new char[sizeof(Derived)];
38
39 // The goal is to trigger a condition when Vptr points to accessible memory,
40 // but VptrPrefix does not. That has been triggering SIGSEGV in UBSan code.
41 void **vtable_ptr = reinterpret_cast<void **>(c);
42 *vtable_ptr = (void*)accessible;
43
44 Derived *list = (Derived *)c;
45
46 // CHECK: PR33221.cpp:[[@LINE+2]]:19: runtime error: member access within address {{.*}} which does not point to an object of type 'Base'
47 // CHECK-NEXT: invalid vptr
48 int foo = list->i;
49 return 0;
50 }
51