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