blob: d101054673b3fca44a4ce777a9a07e56089ce14f [file] [log] [blame]
Peter Collingbournee44acad2018-06-26 02:15:47 +00001// RUN: %clangxx_cfi -o %t %s
2// RUN: %expect_crash %run %t a
3// RUN: %expect_crash %run %t b
4// RUN: %expect_crash %run %t c
5// RUN: %expect_crash %run %t d
6// RUN: %expect_crash %run %t e
7// RUN: %run %t f
8// RUN: %run %t g
9
10// RUN: %clangxx_cfi_diag -o %t2 %s
11// RUN: %run %t2 a 2>&1 | FileCheck --check-prefix=A %s
12// RUN: %run %t2 b 2>&1 | FileCheck --check-prefix=B %s
13// RUN: %run %t2 c 2>&1 | FileCheck --check-prefix=C %s
14// RUN: %run %t2 d 2>&1 | FileCheck --check-prefix=D %s
15// RUN: %run %t2 e 2>&1 | FileCheck --check-prefix=E %s
16
17#include <assert.h>
18#include <string.h>
19
20struct SBase1 {
21 void b1() {}
22};
23
24struct SBase2 {
25 void b2() {}
26};
27
28struct S : SBase1, SBase2 {
29 void f1() {}
30 int f2() { return 1; }
31 virtual void g1() {}
32 virtual int g2() { return 1; }
33 virtual int g3() { return 1; }
34};
35
36struct T {
37 void f1() {}
38 int f2() { return 2; }
39 virtual void g1() {}
40 virtual int g2() { return 2; }
41 virtual void g3() {}
42};
43
44typedef void (S::*S_void)();
45
46typedef int (S::*S_int)();
47typedef int (T::*T_int)();
48
49template <typename To, typename From>
50To bitcast(From f) {
51 assert(sizeof(To) == sizeof(From));
52 To t;
53 memcpy(&t, &f, sizeof(f));
54 return t;
55}
56
57int main(int argc, char **argv) {
58 S s;
59 T t;
60
61 switch (argv[1][0]) {
62 case 'a':
63 // A: runtime error: control flow integrity check for type 'int (S::*)()' failed during non-virtual pointer to member function call
64 // A: note: S::f1() defined here
65 (s.*bitcast<S_int>(&S::f1))();
66 break;
67 case 'b':
68 // B: runtime error: control flow integrity check for type 'int (T::*)()' failed during non-virtual pointer to member function call
69 // B: note: S::f2() defined here
70 (t.*bitcast<T_int>(&S::f2))();
71 break;
72 case 'c':
73 // C: runtime error: control flow integrity check for type 'int (S::*)()' failed during virtual pointer to member function call
74 // C: note: vtable is of type 'S'
75 (s.*bitcast<S_int>(&S::g1))();
76 break;
77 case 'd':
78 // D: runtime error: control flow integrity check for type 'int (S::*)()' failed during virtual pointer to member function call
79 // D: note: vtable is of type 'T'
80 (reinterpret_cast<S &>(t).*&S::g2)();
81 break;
82 case 'e':
83 // E: runtime error: control flow integrity check for type 'void (S::*)()' failed during virtual pointer to member function call
84 // E: note: vtable is of type 'S'
85 (s.*bitcast<S_void>(&T::g3))();
86 break;
87 case 'f':
88 (s.*&SBase1::b1)();
89 break;
90 case 'g':
91 (s.*&SBase2::b2)();
92 break;
93 }
94}