aboutsummaryrefslogtreecommitdiff
path: root/test/cfi/utils.h
diff options
context:
space:
mode:
Diffstat (limited to 'test/cfi/utils.h')
-rw-r--r--test/cfi/utils.h94
1 files changed, 54 insertions, 40 deletions
diff --git a/test/cfi/utils.h b/test/cfi/utils.h
index 5c290d151069..430359d8c50c 100644
--- a/test/cfi/utils.h
+++ b/test/cfi/utils.h
@@ -5,49 +5,63 @@ 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.
+// 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). Instantiating this class will trigger the instantiation of I
+// templates with I virtual tables for classes deriving from T, I-2 of which
+// will be of size sizeof(void*) * 5, 1 of which will be of size sizeof(void*)
+// * 3, and 1 of which will be of size sizeof(void*) * 9. (Under the MS ABI
+// each virtual table will be sizeof(void*) bytes smaller). Each category
+// of virtual tables is aligned to a different power of 2, precluding the
+// all-ones optimization. As a result, the bit vector for the base class will
+// need to contain at least I*2 entries to accommodate all the derived virtual
+// tables.
template <typename T, unsigned I>
-class Deriver : T {
+struct Deriver : T {
+ Deriver() {
+ break_optimization(new Deriver<T, I-1>);
+ }
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() {}
+ virtual void h() {}
};
+template <typename T>
+struct Deriver<T, 0> : T {
+ virtual void f() {}
+ void g() {}
+};
+
+template <typename T>
+struct Deriver<T, 1> : T {
+ Deriver() {
+ break_optimization(new Deriver<T, 0>);
+ }
+ virtual void f() {}
+ virtual void g() {}
+ virtual void h() {}
+ virtual void i() {}
+ virtual void j() {}
+ virtual void k() {}
+ virtual void l() {}
+};
+
+// Instantiate enough classes to force CFI checks for type T to use bit
+// vectors of size 32 (if B32 defined), 64 (if B64 defined) or >64 (if BM
+// defined).
+template <typename T>
+void create_derivers() {
+#ifdef B32
+ break_optimization(new Deriver<T, 10>);
+#endif
+
+#ifdef B64
+ break_optimization(new Deriver<T, 25>);
+#endif
+
+#ifdef BM
+ break_optimization(new Deriver<T, 40>);
+#endif
+}
+
#endif