xref: /aosp_15_r20/external/compiler-rt/test/cfi/base-derived-destructor.cpp (revision 7c3d14c8b49c529e04be81a3ce6f5cc23712e4c6)
1*7c3d14c8STreehugger Robot // RUN: %clangxx_cfi -o %t1 %s
2*7c3d14c8STreehugger Robot // RUN: %expect_crash %t1 2>&1 | FileCheck --check-prefix=CFI %s
3*7c3d14c8STreehugger Robot 
4*7c3d14c8STreehugger Robot // RUN: %clangxx_cfi -DB32 -o %t2 %s
5*7c3d14c8STreehugger Robot // RUN: %expect_crash %t2 2>&1 | FileCheck --check-prefix=CFI %s
6*7c3d14c8STreehugger Robot 
7*7c3d14c8STreehugger Robot // RUN: %clangxx_cfi -DB64 -o %t3 %s
8*7c3d14c8STreehugger Robot // RUN: %expect_crash %t3 2>&1 | FileCheck --check-prefix=CFI %s
9*7c3d14c8STreehugger Robot 
10*7c3d14c8STreehugger Robot // RUN: %clangxx_cfi -DBM -o %t4 %s
11*7c3d14c8STreehugger Robot // RUN: %expect_crash %t4 2>&1 | FileCheck --check-prefix=CFI %s
12*7c3d14c8STreehugger Robot 
13*7c3d14c8STreehugger Robot // RUN: %clangxx_cfi -O1 -o %t5 %s
14*7c3d14c8STreehugger Robot // RUN: %expect_crash %t5 2>&1 | FileCheck --check-prefix=CFI %s
15*7c3d14c8STreehugger Robot 
16*7c3d14c8STreehugger Robot // RUN: %clangxx_cfi -O1 -DB32 -o %t6 %s
17*7c3d14c8STreehugger Robot // RUN: %expect_crash %t6 2>&1 | FileCheck --check-prefix=CFI %s
18*7c3d14c8STreehugger Robot 
19*7c3d14c8STreehugger Robot // RUN: %clangxx_cfi -O1 -DB64 -o %t7 %s
20*7c3d14c8STreehugger Robot // RUN: %expect_crash %t7 2>&1 | FileCheck --check-prefix=CFI %s
21*7c3d14c8STreehugger Robot 
22*7c3d14c8STreehugger Robot // RUN: %clangxx_cfi -O1 -DBM -o %t8 %s
23*7c3d14c8STreehugger Robot // RUN: %expect_crash %t8 2>&1 | FileCheck --check-prefix=CFI %s
24*7c3d14c8STreehugger Robot 
25*7c3d14c8STreehugger Robot // RUN: %clangxx_cfi -O2 -o %t9 %s
26*7c3d14c8STreehugger Robot // RUN: %expect_crash %t9 2>&1 | FileCheck --check-prefix=CFI %s
27*7c3d14c8STreehugger Robot 
28*7c3d14c8STreehugger Robot // RUN: %clangxx_cfi -O2 -DB32 -o %t10 %s
29*7c3d14c8STreehugger Robot // RUN: %expect_crash %t10 2>&1 | FileCheck --check-prefix=CFI %s
30*7c3d14c8STreehugger Robot 
31*7c3d14c8STreehugger Robot // RUN: %clangxx_cfi -O2 -DB64 -o %t11 %s
32*7c3d14c8STreehugger Robot // RUN: %expect_crash %t11 2>&1 | FileCheck --check-prefix=CFI %s
33*7c3d14c8STreehugger Robot 
34*7c3d14c8STreehugger Robot // RUN: %clangxx_cfi -O2 -DBM -o %t12 %s
35*7c3d14c8STreehugger Robot // RUN: %expect_crash %t12 2>&1 | FileCheck --check-prefix=CFI %s
36*7c3d14c8STreehugger Robot 
37*7c3d14c8STreehugger Robot // RUN: %clangxx_cfi -O3 -o %t13 %s
38*7c3d14c8STreehugger Robot // RUN: %expect_crash %t13 2>&1 | FileCheck --check-prefix=CFI %s
39*7c3d14c8STreehugger Robot 
40*7c3d14c8STreehugger Robot // RUN: %clangxx_cfi -O3 -DB32 -o %t14 %s
41*7c3d14c8STreehugger Robot // RUN: %expect_crash %t14 2>&1 | FileCheck --check-prefix=CFI %s
42*7c3d14c8STreehugger Robot 
43*7c3d14c8STreehugger Robot // RUN: %clangxx_cfi -O3 -DB64 -o %t15 %s
44*7c3d14c8STreehugger Robot // RUN: %expect_crash %t15 2>&1 | FileCheck --check-prefix=CFI %s
45*7c3d14c8STreehugger Robot 
46*7c3d14c8STreehugger Robot // RUN: %clangxx_cfi -O3 -DBM -o %t16 %s
47*7c3d14c8STreehugger Robot // RUN: %expect_crash %t16 2>&1 | FileCheck --check-prefix=CFI %s
48*7c3d14c8STreehugger Robot 
49*7c3d14c8STreehugger Robot // RUN: %clangxx_cfi_diag -o %t17 %s
50*7c3d14c8STreehugger Robot // RUN: %t17 2>&1 | FileCheck --check-prefix=CFI-DIAG %s
51*7c3d14c8STreehugger Robot 
52*7c3d14c8STreehugger Robot // RUN: %clangxx -o %t18 %s
53*7c3d14c8STreehugger Robot // RUN: %t18 2>&1 | FileCheck --check-prefix=NCFI %s
54*7c3d14c8STreehugger Robot 
55*7c3d14c8STreehugger Robot // Tests that the CFI mechanism crashes the program when making a
56*7c3d14c8STreehugger Robot // base-to-derived cast from a destructor of the base class,
57*7c3d14c8STreehugger Robot // where both types have virtual tables.
58*7c3d14c8STreehugger Robot 
59*7c3d14c8STreehugger Robot // REQUIRES: cxxabi
60*7c3d14c8STreehugger Robot 
61*7c3d14c8STreehugger Robot #include <stdio.h>
62*7c3d14c8STreehugger Robot #include "utils.h"
63*7c3d14c8STreehugger Robot 
64*7c3d14c8STreehugger Robot template<typename T>
65*7c3d14c8STreehugger Robot class A {
66*7c3d14c8STreehugger Robot  public:
context()67*7c3d14c8STreehugger Robot   T* context() { return static_cast<T*>(this); }
68*7c3d14c8STreehugger Robot 
~A()69*7c3d14c8STreehugger Robot   virtual ~A() {
70*7c3d14c8STreehugger Robot     break_optimization(context());
71*7c3d14c8STreehugger Robot   }
72*7c3d14c8STreehugger Robot };
73*7c3d14c8STreehugger Robot 
74*7c3d14c8STreehugger Robot class B : public A<B> {
75*7c3d14c8STreehugger Robot  public:
~B()76*7c3d14c8STreehugger Robot   virtual ~B() { }
77*7c3d14c8STreehugger Robot };
78*7c3d14c8STreehugger Robot 
main()79*7c3d14c8STreehugger Robot int main() {
80*7c3d14c8STreehugger Robot   // CFI: 1
81*7c3d14c8STreehugger Robot   // NCFI: 1
82*7c3d14c8STreehugger Robot   fprintf(stderr, "1\n");
83*7c3d14c8STreehugger Robot 
84*7c3d14c8STreehugger Robot   // CFI-DIAG: runtime error: control flow integrity check for type 'B' failed during base-to-derived cast
85*7c3d14c8STreehugger Robot   // CFI-DIAG-NEXT: note: vtable is of type '{{(class )?}}A<{{(class )?}}B>'
86*7c3d14c8STreehugger Robot   B* b = new B;
87*7c3d14c8STreehugger Robot   break_optimization(b);
88*7c3d14c8STreehugger Robot   delete b; // UB here
89*7c3d14c8STreehugger Robot 
90*7c3d14c8STreehugger Robot   // CFI-NOT: {{^2$}}
91*7c3d14c8STreehugger Robot   // NCFI: {{^2$}}
92*7c3d14c8STreehugger Robot   fprintf(stderr, "2\n");
93*7c3d14c8STreehugger Robot }
94