Changes the default Windows target triple returned by GetHostTriple.cmake from the old environment names (which we wanted to move away from) to newer, normalized ones. This also requires updating all tests to use the new systems names in constraints. Differential Revision: https://reviews.llvm.org/D47381 llvm-svn: 339307
97 lines
2.5 KiB
C++
97 lines
2.5 KiB
C++
// 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;
|
|
}
|
|
}
|