You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
97 lines
2.5 KiB
97 lines
2.5 KiB
// UNSUPPORTED: windows-msvc
|
|
|
|
// RUN: %clangxx_cfi -o %t %s
|
|
// RUN: %expect_crash %run %t a
|
|
// RUN: %expect_crash %run %t b
|
|
// RUN: %expect_crash %run %t c
|
|
// RUN: %expect_crash %run %t d
|
|
// RUN: %expect_crash %run %t e
|
|
// RUN: %run %t f
|
|
// RUN: %run %t g
|
|
|
|
// RUN: %clangxx_cfi_diag -o %t2 %s
|
|
// RUN: %run %t2 a 2>&1 | FileCheck --check-prefix=A %s
|
|
// RUN: %run %t2 b 2>&1 | FileCheck --check-prefix=B %s
|
|
// RUN: %run %t2 c 2>&1 | FileCheck --check-prefix=C %s
|
|
// RUN: %run %t2 d 2>&1 | FileCheck --check-prefix=D %s
|
|
// RUN: %run %t2 e 2>&1 | FileCheck --check-prefix=E %s
|
|
|
|
#include <assert.h>
|
|
#include <string.h>
|
|
|
|
struct SBase1 {
|
|
void b1() {}
|
|
};
|
|
|
|
struct SBase2 {
|
|
void b2() {}
|
|
};
|
|
|
|
struct S : SBase1, SBase2 {
|
|
void f1() {}
|
|
int f2() { return 1; }
|
|
virtual void g1() {}
|
|
virtual int g2() { return 1; }
|
|
virtual int g3() { return 1; }
|
|
};
|
|
|
|
struct T {
|
|
void f1() {}
|
|
int f2() { return 2; }
|
|
virtual void g1() {}
|
|
virtual int g2() { return 2; }
|
|
virtual void g3() {}
|
|
};
|
|
|
|
typedef void (S::*S_void)();
|
|
|
|
typedef int (S::*S_int)();
|
|
typedef int (T::*T_int)();
|
|
|
|
template <typename To, typename From>
|
|
To bitcast(From f) {
|
|
assert(sizeof(To) == sizeof(From));
|
|
To t;
|
|
memcpy(&t, &f, sizeof(f));
|
|
return t;
|
|
}
|
|
|
|
int main(int argc, char **argv) {
|
|
S s;
|
|
T t;
|
|
|
|
switch (argv[1][0]) {
|
|
case 'a':
|
|
// A: runtime error: control flow integrity check for type 'int (S::*)()' failed during non-virtual pointer to member function call
|
|
// A: note: S::f1() defined here
|
|
(s.*bitcast<S_int>(&S::f1))();
|
|
break;
|
|
case 'b':
|
|
// B: runtime error: control flow integrity check for type 'int (T::*)()' failed during non-virtual pointer to member function call
|
|
// B: note: S::f2() defined here
|
|
(t.*bitcast<T_int>(&S::f2))();
|
|
break;
|
|
case 'c':
|
|
// C: runtime error: control flow integrity check for type 'int (S::*)()' failed during virtual pointer to member function call
|
|
// C: note: vtable is of type 'S'
|
|
(s.*bitcast<S_int>(&S::g1))();
|
|
break;
|
|
case 'd':
|
|
// D: runtime error: control flow integrity check for type 'int (S::*)()' failed during virtual pointer to member function call
|
|
// D: note: vtable is of type 'T'
|
|
(reinterpret_cast<S &>(t).*&S::g2)();
|
|
break;
|
|
case 'e':
|
|
// E: runtime error: control flow integrity check for type 'void (S::*)()' failed during virtual pointer to member function call
|
|
// E: note: vtable is of type 'S'
|
|
(s.*bitcast<S_void>(&T::g3))();
|
|
break;
|
|
case 'f':
|
|
(s.*&SBase1::b1)();
|
|
break;
|
|
case 'g':
|
|
(s.*&SBase2::b2)();
|
|
break;
|
|
}
|
|
}
|