68 lines · c
1#ifndef UTILS_H2#define UTILS_H3 4inline void break_optimization(void *arg) {5 __asm__ __volatile__("" : : "r" (arg) : "memory");6}7 8// Tests will instantiate this class to pad out bit sets to test out the9// various ways we can represent the bit set (32-bit inline, 64-bit inline,10// memory). Instantiating this class will trigger the instantiation of I11// templates with I virtual tables for classes deriving from T, I-2 of which12// will be of size sizeof(void*) * 5, 1 of which will be of size sizeof(void*)13// * 3, and 1 of which will be of size sizeof(void*) * 9. (Under the MS ABI14// each virtual table will be sizeof(void*) bytes smaller). Each category15// of virtual tables is aligned to a different power of 2, precluding the16// all-ones optimization. As a result, the bit vector for the base class will17// need to contain at least I*2 entries to accommodate all the derived virtual18// tables.19template <typename T, unsigned I>20struct Deriver : T {21 Deriver() {22 break_optimization(new Deriver<T, I-1>);23 }24 virtual void f() {}25 virtual void g() {}26 virtual void h() {}27};28 29template <typename T>30struct Deriver<T, 0> : T {31 virtual void f() {}32 void g() {}33};34 35template <typename T>36struct Deriver<T, 1> : T {37 Deriver() {38 break_optimization(new Deriver<T, 0>);39 }40 virtual void f() {}41 virtual void g() {}42 virtual void h() {}43 virtual void i() {}44 virtual void j() {}45 virtual void k() {}46 virtual void l() {}47};48 49// Instantiate enough classes to force CFI checks for type T to use bit50// vectors of size 32 (if B32 defined), 64 (if B64 defined) or >64 (if BM51// defined).52template <typename T>53void create_derivers() {54#ifdef B3255 break_optimization(new Deriver<T, 10>);56#endif57 58#ifdef B6459 break_optimization(new Deriver<T, 25>);60#endif61 62#ifdef BM63 break_optimization(new Deriver<T, 40>);64#endif65}66 67#endif68