diff options
author | Peter Collingbourne <peter@pcc.me.uk> | 2015-02-21 01:36:08 +0000 |
---|---|---|
committer | Peter Collingbourne <peter@pcc.me.uk> | 2015-02-21 01:36:08 +0000 |
commit | 4f329a291f815d455decdbccb3c61a22226f43f1 (patch) | |
tree | b8b202369090b42fc0230ccff2eb28814dd8a042 | |
parent | 061391b2a6bc3cded72268ab3af4677cb6fca45e (diff) |
CFI: Add tests for 32-bit, 64-bit and memory bitsets. Break optimization in more places.
git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@230116 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | test/cfi/anon-namespace.cpp | 32 | ||||
-rw-r--r-- | test/cfi/multiple-inheritance.cpp | 35 | ||||
-rw-r--r-- | test/cfi/overwrite.cpp | 26 | ||||
-rw-r--r-- | test/cfi/simple-fail.cpp | 26 | ||||
-rw-r--r-- | test/cfi/simple-pass.cpp | 4 | ||||
-rw-r--r-- | test/cfi/utils.h | 53 | ||||
-rw-r--r-- | test/cfi/vdtor.cpp | 26 |
7 files changed, 199 insertions, 3 deletions
diff --git a/test/cfi/anon-namespace.cpp b/test/cfi/anon-namespace.cpp index f634ab352..0c2c68996 100644 --- a/test/cfi/anon-namespace.cpp +++ b/test/cfi/anon-namespace.cpp @@ -3,6 +3,21 @@ // RUN: %clangxx_cfi -o %t %t1.o %t2.o // RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s +// RUN: %clangxx_cfi -c -DTU1 -DB32 -o %t1.o %s +// RUN: %clangxx_cfi -c -DTU2 -DB32 -o %t2.o %S/../cfi/anon-namespace.cpp +// RUN: %clangxx_cfi -o %t %t1.o %t2.o +// RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s + +// RUN: %clangxx_cfi -c -DTU1 -DB64 -o %t1.o %s +// RUN: %clangxx_cfi -c -DTU2 -DB64 -o %t2.o %S/../cfi/anon-namespace.cpp +// RUN: %clangxx_cfi -o %t %t1.o %t2.o +// RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s + +// RUN: %clangxx_cfi -c -DTU1 -DBM -o %t1.o %s +// RUN: %clangxx_cfi -c -DTU2 -DBM -o %t2.o %S/../cfi/anon-namespace.cpp +// RUN: %clangxx_cfi -o %t %t1.o %t2.o +// RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s + // RUN: %clangxx -c -DTU1 -o %t1.o %s // RUN: %clangxx -c -DTU2 -o %t2.o %S/../cfi/anon-namespace.cpp // RUN: %clangxx -o %t %t1.o %t2.o @@ -19,6 +34,7 @@ // so we have to mangle the file path into the bitset name. #include <stdio.h> +#include "utils.h" struct A { virtual void f() = 0; @@ -45,7 +61,23 @@ A *mkb() { #ifdef TU2 int main() { +#ifdef B32 + break_optimization(new Deriver<B, 0>); +#endif + +#ifdef B64 + break_optimization(new Deriver<B, 0>); + break_optimization(new Deriver<B, 1>); +#endif + +#ifdef BM + break_optimization(new Deriver<B, 0>); + break_optimization(new Deriver<B, 1>); + break_optimization(new Deriver<B, 2>); +#endif + A *a = mkb(); + break_optimization(a); // CFI: 1 // NCFI: 1 diff --git a/test/cfi/multiple-inheritance.cpp b/test/cfi/multiple-inheritance.cpp index 1b03af4a1..523af6f72 100644 --- a/test/cfi/multiple-inheritance.cpp +++ b/test/cfi/multiple-inheritance.cpp @@ -2,6 +2,18 @@ // RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s // RUN: not --crash %t x 2>&1 | FileCheck --check-prefix=CFI %s +// RUN: %clangxx_cfi -DB32 -o %t %s +// RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s +// RUN: not --crash %t x 2>&1 | FileCheck --check-prefix=CFI %s + +// RUN: %clangxx_cfi -DB64 -o %t %s +// RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s +// RUN: not --crash %t x 2>&1 | FileCheck --check-prefix=CFI %s + +// RUN: %clangxx_cfi -DBM -o %t %s +// RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s +// RUN: not --crash %t x 2>&1 | FileCheck --check-prefix=CFI %s + // RUN: %clangxx -o %t %s // RUN: %t 2>&1 | FileCheck --check-prefix=NCFI %s // RUN: %t x 2>&1 | FileCheck --check-prefix=NCFI %s @@ -10,6 +22,7 @@ // permits calls via virtual tables for the correct base class. #include <stdio.h> +#include "utils.h" struct A { virtual void f() = 0; @@ -27,7 +40,29 @@ void C::f() {} void C::g() {} int main(int argc, char **argv) { +#ifdef B32 + break_optimization(new Deriver<A, 0>); + break_optimization(new Deriver<B, 0>); +#endif + +#ifdef B64 + break_optimization(new Deriver<A, 0>); + break_optimization(new Deriver<A, 1>); + break_optimization(new Deriver<B, 0>); + break_optimization(new Deriver<B, 1>); +#endif + +#ifdef BM + break_optimization(new Deriver<A, 0>); + break_optimization(new Deriver<A, 1>); + break_optimization(new Deriver<A, 2>); + break_optimization(new Deriver<B, 0>); + break_optimization(new Deriver<B, 1>); + break_optimization(new Deriver<B, 2>); +#endif + C *c = new C; + break_optimization(c); // CFI: 1 // NCFI: 1 diff --git a/test/cfi/overwrite.cpp b/test/cfi/overwrite.cpp index 74cb3fdcb..d7e58d927 100644 --- a/test/cfi/overwrite.cpp +++ b/test/cfi/overwrite.cpp @@ -1,6 +1,15 @@ // RUN: %clangxx_cfi -o %t %s // RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s +// RUN: %clangxx_cfi -DB32 -o %t %s +// RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s + +// RUN: %clangxx_cfi -DB64 -o %t %s +// RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s + +// RUN: %clangxx_cfi -DBM -o %t %s +// RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s + // RUN: %clangxx -o %t %s // RUN: %t 2>&1 | FileCheck --check-prefix=NCFI %s @@ -10,6 +19,7 @@ // attempting to make a call through it. #include <stdio.h> +#include "utils.h" struct A { virtual void f(); @@ -24,8 +34,24 @@ void foo() { void *fake_vtable[] = { (void *)&foo }; int main() { +#ifdef B32 + break_optimization(new Deriver<A, 0>); +#endif + +#ifdef B64 + break_optimization(new Deriver<A, 0>); + break_optimization(new Deriver<A, 1>); +#endif + +#ifdef BM + break_optimization(new Deriver<A, 0>); + break_optimization(new Deriver<A, 1>); + break_optimization(new Deriver<A, 2>); +#endif + A *a = new A; *((void **)a) = fake_vtable; // UB here + break_optimization(a); // CFI: 1 // NCFI: 1 diff --git a/test/cfi/simple-fail.cpp b/test/cfi/simple-fail.cpp index de3b7ed1b..d8f3b487c 100644 --- a/test/cfi/simple-fail.cpp +++ b/test/cfi/simple-fail.cpp @@ -1,6 +1,15 @@ // RUN: %clangxx_cfi -o %t %s // RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s +// RUN: %clangxx_cfi -DB32 -o %t %s +// RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s + +// RUN: %clangxx_cfi -DB64 -o %t %s +// RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s + +// RUN: %clangxx_cfi -DBM -o %t %s +// RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s + // RUN: %clangxx -o %t %s // RUN: %t 2>&1 | FileCheck --check-prefix=NCFI %s @@ -9,6 +18,7 @@ // pointer to such an object and attempting to make a call through it. #include <stdio.h> +#include "utils.h" struct A { virtual void f(); @@ -23,7 +33,23 @@ struct B { void B::f() {} int main() { +#ifdef B32 + break_optimization(new Deriver<B, 0>); +#endif + +#ifdef B64 + break_optimization(new Deriver<B, 0>); + break_optimization(new Deriver<B, 1>); +#endif + +#ifdef BM + break_optimization(new Deriver<B, 0>); + break_optimization(new Deriver<B, 1>); + break_optimization(new Deriver<B, 2>); +#endif + A *a = new A; + break_optimization(a); // CFI: 1 // NCFI: 1 diff --git a/test/cfi/simple-pass.cpp b/test/cfi/simple-pass.cpp index e8eb3939c..50e7d9256 100644 --- a/test/cfi/simple-pass.cpp +++ b/test/cfi/simple-pass.cpp @@ -5,9 +5,7 @@ // kinds of valid calls involving classes with various different linkages and // types of inheritance. -inline void break_optimization(void *arg) { - __asm__ __volatile__("" : : "r" (arg) : "memory"); -} +#include "utils.h" struct A { virtual void f(); diff --git a/test/cfi/utils.h b/test/cfi/utils.h new file mode 100644 index 000000000..5c290d151 --- /dev/null +++ b/test/cfi/utils.h @@ -0,0 +1,53 @@ +#ifndef UTILS_H +#define UTILS_H + +inline void break_optimization(void *arg) { + __asm__ __volatile__("" : : "r" (arg) : "memory"); +} + +// Tests will instantiate this class to pad out bit sets to test out the various +// ways we can represent the bit set (32-bit inline, 64-bit inline, memory). +// This class has 37 virtual member functions, which forces us to use a +// pointer-aligned bitset. +template <typename T, unsigned I> +class Deriver : T { + virtual void f() {} + virtual void g() {} + virtual void f1() {} + virtual void f2() {} + virtual void f3() {} + virtual void f4() {} + virtual void f5() {} + virtual void f6() {} + virtual void f7() {} + virtual void f8() {} + virtual void f9() {} + virtual void f10() {} + virtual void f11() {} + virtual void f12() {} + virtual void f13() {} + virtual void f14() {} + virtual void f15() {} + virtual void f16() {} + virtual void f17() {} + virtual void f18() {} + virtual void f19() {} + virtual void f20() {} + virtual void f21() {} + virtual void f22() {} + virtual void f23() {} + virtual void f24() {} + virtual void f25() {} + virtual void f26() {} + virtual void f27() {} + virtual void f28() {} + virtual void f29() {} + virtual void f30() {} + virtual void f31() {} + virtual void f32() {} + virtual void f33() {} + virtual void f34() {} + virtual void f35() {} +}; + +#endif diff --git a/test/cfi/vdtor.cpp b/test/cfi/vdtor.cpp index f8101bac8..e21883c38 100644 --- a/test/cfi/vdtor.cpp +++ b/test/cfi/vdtor.cpp @@ -1,6 +1,15 @@ // RUN: %clangxx_cfi -o %t %s // RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s +// RUN: %clangxx_cfi -DB32 -o %t %s +// RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s + +// RUN: %clangxx_cfi -DB64 -o %t %s +// RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s + +// RUN: %clangxx_cfi -DBM -o %t %s +// RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s + // RUN: %clangxx -o %t %s // RUN: %t 2>&1 | FileCheck --check-prefix=NCFI %s @@ -8,6 +17,7 @@ // via 'delete'. #include <stdio.h> +#include "utils.h" struct A { virtual ~A(); @@ -22,7 +32,23 @@ struct B { B::~B() {} int main() { +#ifdef B32 + break_optimization(new Deriver<B, 0>); +#endif + +#ifdef B64 + break_optimization(new Deriver<B, 0>); + break_optimization(new Deriver<B, 1>); +#endif + +#ifdef BM + break_optimization(new Deriver<B, 0>); + break_optimization(new Deriver<B, 1>); + break_optimization(new Deriver<B, 2>); +#endif + A *a = new A; + break_optimization(a); // CFI: 1 // NCFI: 1 |