Run DCE after a LoopFlatten test to reduce spurious output [nfc]
[llvm-project.git] / compiler-rt / test / cfi / mfcall.cpp
blobd4666df8d53331404c5c725930392f78ec782490
1 // UNSUPPORTED: target={{.*windows-msvc.*}}
3 // RUN: %clangxx_cfi -o %t %s
4 // RUN: %expect_crash %run %t a
5 // RUN: %expect_crash %run %t b
6 // RUN: %expect_crash %run %t c
7 // RUN: %expect_crash %run %t d
8 // RUN: %expect_crash %run %t e
9 // RUN: %run %t f
10 // RUN: %run %t g
12 // RUN: %clangxx_cfi_diag -o %t2 %s
13 // RUN: %run %t2 a 2>&1 | FileCheck --check-prefix=A %s
14 // RUN: %run %t2 b 2>&1 | FileCheck --check-prefix=B %s
15 // RUN: %run %t2 c 2>&1 | FileCheck --check-prefix=C %s
16 // RUN: %run %t2 d 2>&1 | FileCheck --check-prefix=D %s
17 // RUN: %run %t2 e 2>&1 | FileCheck --check-prefix=E %s
19 #include <assert.h>
20 #include <string.h>
22 struct SBase1 {
23 void b1() {}
26 struct SBase2 {
27 void b2() {}
30 struct S : SBase1, SBase2 {
31 void f1() {}
32 int f2() { return 1; }
33 virtual void g1() {}
34 virtual int g2() { return 1; }
35 virtual int g3() { return 1; }
38 struct T {
39 void f1() {}
40 int f2() { return 2; }
41 virtual void g1() {}
42 virtual int g2() { return 2; }
43 virtual void g3() {}
46 typedef void (S::*S_void)();
48 typedef int (S::*S_int)();
49 typedef int (T::*T_int)();
51 template <typename To, typename From>
52 To bitcast(From f) {
53 assert(sizeof(To) == sizeof(From));
54 To t;
55 memcpy(&t, &f, sizeof(f));
56 return t;
59 int main(int argc, char **argv) {
60 S s;
61 T t;
63 switch (argv[1][0]) {
64 case 'a':
65 // A: runtime error: control flow integrity check for type 'int (S::*)()' failed during non-virtual pointer to member function call
66 // A: note: S::f1() defined here
67 (s.*bitcast<S_int>(&S::f1))();
68 break;
69 case 'b':
70 // B: runtime error: control flow integrity check for type 'int (T::*)()' failed during non-virtual pointer to member function call
71 // B: note: S::f2() defined here
72 (t.*bitcast<T_int>(&S::f2))();
73 break;
74 case 'c':
75 // C: runtime error: control flow integrity check for type 'int (S::*)()' failed during virtual pointer to member function call
76 // C: note: vtable is of type 'S'
77 (s.*bitcast<S_int>(&S::g1))();
78 break;
79 case 'd':
80 // D: runtime error: control flow integrity check for type 'int (S::*)()' failed during virtual pointer to member function call
81 // D: note: vtable is of type 'T'
82 (reinterpret_cast<S &>(t).*&S::g2)();
83 break;
84 case 'e':
85 // E: runtime error: control flow integrity check for type 'void (S::*)()' failed during virtual pointer to member function call
86 // E: note: vtable is of type 'S'
87 (s.*bitcast<S_void>(&T::g3))();
88 break;
89 case 'f':
90 (s.*&SBase1::b1)();
91 break;
92 case 'g':
93 (s.*&SBase2::b2)();
94 break;