]>
git.proxmox.com Git - rustc.git/blob - src/compiler-rt/test/ubsan/TestCases/TypeCheck/vptr.cpp
1 // RUN: %clangxx -frtti -fsanitize=vptr -fno-sanitize-recover=vptr -g %s -O3 -o %t
2 // RUN: %run %t rT && %run %t mT && %run %t fT && %run %t cT
3 // RUN: %run %t rU && %run %t mU && %run %t fU && %run %t cU
4 // RUN: %run %t rS && %run %t rV && %run %t oV
5 // RUN: %env_ubsan_opts=print_stacktrace=1 not %run %t mS 2>&1 | FileCheck %s --check-prefix=CHECK-MEMBER --check-prefix=CHECK-%os-MEMBER --strict-whitespace
6 // RUN: %env_ubsan_opts=print_stacktrace=1 not %run %t fS 2>&1 | FileCheck %s --check-prefix=CHECK-MEMFUN --strict-whitespace
7 // RUN: %env_ubsan_opts=print_stacktrace=1 not %run %t cS 2>&1 | FileCheck %s --check-prefix=CHECK-DOWNCAST --check-prefix=CHECK-%os-DOWNCAST --strict-whitespace
8 // RUN: %env_ubsan_opts=print_stacktrace=1 not %run %t mV 2>&1 | FileCheck %s --check-prefix=CHECK-MEMBER --check-prefix=CHECK-%os-MEMBER --strict-whitespace
9 // RUN: %env_ubsan_opts=print_stacktrace=1 not %run %t fV 2>&1 | FileCheck %s --check-prefix=CHECK-MEMFUN --strict-whitespace
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 // 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
14 // RUN: (echo "vptr_check:S"; echo "vptr_check:T"; echo "vptr_check:U") > %t.supp
15 // RUN: %env_ubsan_opts=suppressions='"%t.supp"' %run %t mS
16 // RUN: %env_ubsan_opts=suppressions='"%t.supp"' %run %t fS
17 // RUN: %env_ubsan_opts=suppressions='"%t.supp"' %run %t cS
18 // RUN: %env_ubsan_opts=suppressions='"%t.supp"' %run %t mV
19 // RUN: %env_ubsan_opts=suppressions='"%t.supp"' %run %t fV
20 // RUN: %env_ubsan_opts=suppressions='"%t.supp"' %run %t cV
21 // RUN: %env_ubsan_opts=suppressions='"%t.supp"' %run %t oU
23 // RUN: echo "vptr_check:S" > %t.loc-supp
24 // RUN: %env_ubsan_opts=suppressions='"%t.loc-supp"' not %run %t x- 2>&1 | FileCheck %s --check-prefix=CHECK-LOC-SUPPRESS
26 // REQUIRES: stable-runtime, cxxabi
36 virtual int v () { return 0 ; }
43 virtual int v () { return 1 ; }
46 struct U
: S
, T
{ virtual int v () { return 2 ; } };
50 // Make p global so that lsan does not complain.
53 int access_p ( T
* p
, char type
);
55 int main ( int argc
, char ** argv
) {
57 fprintf ( stderr
, "Test case: %s \n " , argv
[ 1 ]);
75 char Buffer
[ sizeof ( U
)] = {};
76 char TStorage
[ sizeof ( T
)];
79 p
= reinterpret_cast < T
*>( Buffer
);
82 // Make sure p points to the memory chunk of sufficient size to prevent ASan
83 // reports about out-of-bounds access.
84 p
= reinterpret_cast < T
*>( new ( TStorage
) S
);
93 p
= reinterpret_cast < T
*>( new U
);
97 access_p ( p
, argv
[ 1 ][ 0 ]);
101 int access_p ( T
* p
, char type
) {
104 // Binding a reference to storage of appropriate size and alignment is OK.
109 for ( int i
= 0 ; i
< 2 ; i
++) {
110 // Check that the first iteration ("S") succeeds, while the second ("V") fails.
111 p
= reinterpret_cast < T
*>(( i
== 0 ) ? new S
: new V
);
112 // CHECK-LOC-SUPPRESS: vptr.cpp:[[@LINE+5]]:7: runtime error: member call on address [[PTR:0x[0-9a-f]*]] which does not point to an object of type 'T'
113 // CHECK-LOC-SUPPRESS-NEXT: [[PTR]]: note: object is of type 'V'
114 // CHECK-LOC-SUPPRESS-NEXT: {{^ .. .. .. .. .. .. .. .. .. .. .. .. }}
115 // CHECK-LOC-SUPPRESS-NEXT: {{^ \^~~~~~~~~~~(~~~~~~~~~~~~)? *$}}
116 // CHECK-LOC-SUPPRESS-NEXT: {{^ vptr for 'V'}}
122 // CHECK-MEMBER: vptr.cpp:[[@LINE+6]]:15: runtime error: member access within address [[PTR:0x[0-9a-f]*]] which does not point to an object of type 'T'
123 // CHECK-MEMBER-NEXT: [[PTR]]: note: object is of type [[DYN_TYPE:'S'|'U']]
124 // CHECK-MEMBER-NEXT: {{^ .. .. .. .. .. .. .. .. .. .. .. .. }}
125 // CHECK-MEMBER-NEXT: {{^ \^~~~~~~~~~~(~~~~~~~~~~~~)? *$}}
126 // CHECK-MEMBER-NEXT: {{^ vptr for}} [[DYN_TYPE]]
127 // CHECK-Linux-MEMBER: #0 {{.*}}access_p{{.*}}vptr.cpp:[[@LINE+1]]
130 // 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'
131 // CHECK-NULL-MEMBER-NEXT: [[PTR]]: note: object has invalid vptr
132 // CHECK-NULL-MEMBER-NEXT: {{^ ?.. .. .. .. ?00 00 00 00 ?00 00 00 00 ?}}
133 // CHECK-NULL-MEMBER-NEXT: {{^ \^~~~~~~~~~~(~~~~~~~~~~~~)? *$}}
134 // CHECK-NULL-MEMBER-NEXT: {{^ invalid vptr}}
135 // CHECK-Linux-NULL-MEMBER: #0 {{.*}}access_p{{.*}}vptr.cpp:[[@LINE-7]]
138 // CHECK-MEMFUN: vptr.cpp:[[@LINE+6]]:12: runtime error: member call on address [[PTR:0x[0-9a-f]*]] which does not point to an object of type 'T'
139 // CHECK-MEMFUN-NEXT: [[PTR]]: note: object is of type [[DYN_TYPE:'S'|'U']]
140 // CHECK-MEMFUN-NEXT: {{^ .. .. .. .. .. .. .. .. .. .. .. .. }}
141 // CHECK-MEMFUN-NEXT: {{^ \^~~~~~~~~~~(~~~~~~~~~~~~)? *$}}
142 // CHECK-MEMFUN-NEXT: {{^ vptr for}} [[DYN_TYPE]]
143 // TODO: Add check for stacktrace here.
147 // CHECK-OFFSET: vptr.cpp:[[@LINE+6]]:12: runtime error: member call on address [[PTR:0x[0-9a-f]*]] which does not point to an object of type 'U'
148 // CHECK-OFFSET-NEXT: 0x{{[0-9a-f]*}}: note: object is base class subobject at offset {{8|16}} within object of type [[DYN_TYPE:'U']]
149 // CHECK-OFFSET-NEXT: {{^ .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. }}
150 // CHECK-OFFSET-NEXT: {{^ \^ ( ~~~~~~~~~~~~)?~~~~~~~~~~~ *$}}
151 // CHECK-OFFSET-NEXT: {{^ ( )?vptr for}} 'T' base class of [[DYN_TYPE]]
152 // CHECK-Linux-OFFSET: #0 {{.*}}access_p{{.*}}vptr.cpp:[[@LINE+1]]
153 return reinterpret_cast < U
*>( p
)-> v () - 2 ;
156 // CHECK-DOWNCAST: vptr.cpp:[[@LINE+6]]:11: runtime error: downcast of address [[PTR:0x[0-9a-f]*]] which does not point to an object of type 'T'
157 // CHECK-DOWNCAST-NEXT: [[PTR]]: note: object is of type [[DYN_TYPE:'S'|'U']]
158 // CHECK-DOWNCAST-NEXT: {{^ .. .. .. .. .. .. .. .. .. .. .. .. }}
159 // CHECK-DOWNCAST-NEXT: {{^ \^~~~~~~~~~~(~~~~~~~~~~~~)? *$}}
160 // CHECK-DOWNCAST-NEXT: {{^ vptr for}} [[DYN_TYPE]]
161 // CHECK-Linux-DOWNCAST: #0 {{.*}}access_p{{.*}}vptr.cpp:[[@LINE+1]]
162 ( void ) static_cast < T
*>( reinterpret_cast < S
*>( p
));