|
1 |
| -// RUN: %clangxx -frtti -fsanitize=vptr -fno-sanitize-recover=vptr -g %s -O3 -o %t -mllvm -enable-tail-merge=false |
| 1 | +// RUN: %clangxx -frtti -fsanitize=null,vptr -fno-sanitize-recover=null,vptr -g %s -O3 -o %t -mllvm -enable-tail-merge=false |
2 | 2 | // RUN: %run %t rT && %run %t mT && %run %t fT && %run %t cT
|
3 | 3 | // RUN: %run %t rU && %run %t mU && %run %t fU && %run %t cU
|
4 | 4 | // RUN: %run %t rS && %run %t rV && %run %t oV
|
|
9 | 9 | // RUN: %env_ubsan_opts=print_stacktrace=1 not %run %t fV 2>&1 | FileCheck %s --check-prefix=CHECK-MEMFUN --strict-whitespace
|
10 | 10 | // RUN: %env_ubsan_opts=print_stacktrace=1 not %run %t cV 2>&1 | FileCheck %s --check-prefix=CHECK-DOWNCAST --check-prefix=CHECK-%os-DOWNCAST --strict-whitespace
|
11 | 11 | // RUN: %env_ubsan_opts=print_stacktrace=1 not %run %t oU 2>&1 | FileCheck %s --check-prefix=CHECK-OFFSET --check-prefix=CHECK-%os-OFFSET --strict-whitespace
|
12 |
| -// RUN: %env_ubsan_opts=print_stacktrace=1 not %run %t m0 2>&1 | FileCheck %s --check-prefix=CHECK-NULL-MEMBER --check-prefix=CHECK-%os-NULL-MEMBER --strict-whitespace |
| 12 | +// RUN: %env_ubsan_opts=print_stacktrace=1 not %run %t m0 2>&1 | FileCheck %s --check-prefix=CHECK-INVALID-MEMBER --check-prefix=CHECK-%os-NULL-MEMBER --strict-whitespace |
| 13 | +// RUN: %env_ubsan_opts=print_stacktrace=1 not %run %t m0 2>&1 | FileCheck %s --check-prefix=CHECK-INVALID-MEMBER --check-prefix=CHECK-%os-NULL-MEMBER --strict-whitespace |
| 14 | +// RUN: not %run %t nN 2>&1 | FileCheck %s --check-prefix=CHECK-NULL-MEMFUN --strict-whitespace |
13 | 15 |
|
14 | 16 | // RUN: (echo "vptr_check:S"; echo "vptr_check:T"; echo "vptr_check:U") > %t.supp
|
15 | 17 | // RUN: %env_ubsan_opts=suppressions='"%t.supp"' %run %t mS
|
@@ -99,6 +101,9 @@ int main(int argc, char **argv) {
|
99 | 101 | case 'V':
|
100 | 102 | p = reinterpret_cast<T*>(new U);
|
101 | 103 | break;
|
| 104 | + case 'N': |
| 105 | + p = 0; |
| 106 | + break; |
102 | 107 | }
|
103 | 108 |
|
104 | 109 | access_p(p, argv[1][0]);
|
@@ -134,11 +139,11 @@ int access_p(T *p, char type) {
|
134 | 139 | // CHECK-Linux-MEMBER: #0 {{.*}}access_p{{.*}}vptr.cpp:[[@LINE+1]]
|
135 | 140 | return p->b;
|
136 | 141 |
|
137 |
| - // CHECK-NULL-MEMBER: vptr.cpp:[[@LINE-2]]:15: runtime error: member access within address [[PTR:0x[0-9a-f]*]] which does not point to an object of type 'T' |
138 |
| - // CHECK-NULL-MEMBER-NEXT: [[PTR]]: note: object has invalid vptr |
139 |
| - // CHECK-NULL-MEMBER-NEXT: {{^ ?.. .. .. .. ?00 00 00 00 ?00 00 00 00 ?}} |
140 |
| - // CHECK-NULL-MEMBER-NEXT: {{^ \^~~~~~~~~~~(~~~~~~~~~~~~)? *$}} |
141 |
| - // CHECK-NULL-MEMBER-NEXT: {{^ invalid vptr}} |
| 142 | + // CHECK-INVALID-MEMBER: vptr.cpp:[[@LINE-2]]:15: runtime error: member access within address [[PTR:0x[0-9a-f]*]] which does not point to an object of type 'T' |
| 143 | + // CHECK-INVALID-MEMBER-NEXT: [[PTR]]: note: object has invalid vptr |
| 144 | + // CHECK-INVALID-MEMBER-NEXT: {{^ ?.. .. .. .. ?00 00 00 00 ?00 00 00 00 ?}} |
| 145 | + // CHECK-INVALID-MEMBER-NEXT: {{^ \^~~~~~~~~~~(~~~~~~~~~~~~)? *$}} |
| 146 | + // CHECK-INVALID-MEMBER-NEXT: {{^ invalid vptr}} |
142 | 147 | // CHECK-Linux-NULL-MEMBER: #0 {{.*}}access_p{{.*}}vptr.cpp:[[@LINE-7]]
|
143 | 148 |
|
144 | 149 | case 'f':
|
@@ -168,6 +173,10 @@ int access_p(T *p, char type) {
|
168 | 173 | // CHECK-Linux-DOWNCAST: #0 {{.*}}access_p{{.*}}vptr.cpp:[[@LINE+1]]
|
169 | 174 | (void)static_cast<T*>(reinterpret_cast<S*>(p));
|
170 | 175 | return 0;
|
| 176 | + |
| 177 | + case 'n': |
| 178 | + // CHECK-NULL-MEMFUN: vptr.cpp:[[@LINE+1]]:15: runtime error: member call on null pointer of type 'T' |
| 179 | + return p->g(); |
171 | 180 | }
|
172 | 181 | return 0;
|
173 | 182 | }
|
0 commit comments