template <typename a, a b>
void *c(void *d) { return __builtin_align_down(d, b);
}
struct x {};
x foo;
void test(void *value) {
c<int, 16>(value);
c<struct x, foo>(value); }
template <typename T, long Alignment, long ArraySize = 16>
void test_templated_arguments() {
T array[ArraySize]; static_assert(__is_same(decltype(__builtin_align_up(array, Alignment)), T *), "return type should be the decayed array type");
static_assert(__is_same(decltype(__builtin_align_down(array, Alignment)), T *),
"return type should be the decayed array type");
static_assert(__is_same(decltype(__builtin_is_aligned(array, Alignment)), bool),
"return type should be bool");
T *x1 = __builtin_align_up(array, Alignment);
T *x2 = __builtin_align_down(array, Alignment);
bool x3 = __builtin_align_up(array, Alignment);
}
void test() {
test_templated_arguments<int, 32>(); test_templated_arguments<struct fwddecl, 16>();
test_templated_arguments<int, 7>(); }
template <typename T, long ArraySize>
void test_incorrect_alignment_without_instatiation(T value) {
int array[32];
static_assert(__is_same(decltype(__builtin_align_up(array, 31)), int *), "return type should be the decayed array type");
static_assert(__is_same(decltype(__builtin_align_down(array, 7)), int *), "return type should be the decayed array type");
static_assert(__is_same(decltype(__builtin_is_aligned(array, -1)), bool), "return type should be bool");
__builtin_align_up(array); __builtin_align_up(array, 31); __builtin_align_down(array, 31); __builtin_align_up(array, 31); __builtin_align_up(value, 31); __builtin_align_up(value);
__builtin_align_up(array, sizeof(sizeof(value)) - 1); __builtin_align_up(array, value); (void)__builtin_align_up(array, ArraySize); }
typedef __SIZE_TYPE__ size_t;
void *allocate_impl(size_t size);
template <typename T>
T *allocate() {
constexpr size_t allocation_size =
__builtin_align_up(sizeof(T), sizeof(void *));
return static_cast<T *>(
__builtin_assume_aligned(allocate_impl(allocation_size), sizeof(void *)));
}
struct Foo {
int value;
};
void *test2() {
return allocate<struct Foo>();
}
class MemPtr {
public:
int data;
void func();
virtual void vfunc();
};
void test_member_ptr() {
__builtin_align_up(&MemPtr::data, 64); __builtin_align_down(&MemPtr::func, 64); __builtin_is_aligned(&MemPtr::vfunc, 64); }
void test_references(Foo &i) {
(void)__builtin_align_up(i, 64); (void)__builtin_align_up(static_cast<Foo &>(i), 64); (void)__builtin_align_up(static_cast<const Foo &>(i), 64); (void)__builtin_align_up(static_cast<Foo &&>(i), 64); (void)__builtin_align_up(static_cast<const Foo &&>(i), 64); (void)__builtin_align_up(&i, 64);
}
template <typename T>
constexpr bool wrap_is_aligned(T ptr, long align) {
return __builtin_is_aligned(ptr, align);
}
template <typename T>
constexpr T wrap_align_up(T ptr, long align) {
return __builtin_align_up(ptr, align);
}
template <typename T>
constexpr T wrap_align_down(T ptr, long align) {
return __builtin_align_down(ptr, align);
}
constexpr int a1 = wrap_align_up(22, 32);
static_assert(a1 == 32, "");
constexpr int a2 = wrap_align_down(22, 16);
static_assert(a2 == 16, "");
constexpr bool a3 = wrap_is_aligned(22, 32);
static_assert(!a3, "");
static_assert(wrap_align_down(wrap_align_up(22, 16), 32) == 32, "");
static_assert(wrap_is_aligned(wrap_align_down(wrap_align_up(22, 16), 32), 32), "");
static_assert(!wrap_is_aligned(wrap_align_down(wrap_align_up(22, 16), 32), 64), "");
constexpr long const_value(long l) { return l; }
static_assert(wrap_align_down(1, const_value(-1)), ""); static_assert(wrap_align_up(1, const_value(-2)), ""); static_assert(wrap_is_aligned(1, const_value(-3)), ""); static_assert(wrap_align_down(1, const_value(17)), ""); static_assert(wrap_align_up(1, const_value(18)), ""); static_assert(wrap_is_aligned(1, const_value(19)), "");
static_assert(wrap_align_down(static_cast<short>(1), const_value(1 << 20)), ""); static_assert(wrap_align_up(static_cast<int>(1), const_value(1ull << 33)), ""); static_assert(wrap_is_aligned(static_cast<char>(1), const_value(1 << 22)), "");
static_assert(wrap_align_up(static_cast<bool>(1), const_value(1 << 21)), "");
_Alignas(32) char align32array[128];
static_assert(&align32array[0] == &align32array[0], "");
static_assert(__builtin_align_up(&align32array[0], 32) == &align32array[0], "");
static_assert(__builtin_align_up(&align32array[0], 4) == &align32array[0], "");
static_assert(__builtin_align_down(&align32array[0], 4) == __builtin_align_up(&align32array[0], 8), "");
static_assert(&align32array[0] == __builtin_align_up(&align32array[0], 64), ""); static_assert(__builtin_align_up(&align32array[0], 64) == __builtin_align_up(&align32array[0], 64), "");
static_assert(__builtin_align_up(&align32array[0], 4) == &align32array[0], "");
static_assert(__builtin_align_up(&align32array[1], 4) == &align32array[4], "");
static_assert(__builtin_align_up(&align32array[2], 4) == &align32array[4], "");
static_assert(__builtin_align_up(&align32array[3], 4) == &align32array[4], "");
static_assert(__builtin_align_up(&align32array[4], 4) == &align32array[4], "");
static_assert(__builtin_align_up(&align32array[5], 4) == &align32array[8], "");
static_assert(__builtin_align_up(&align32array[6], 4) == &align32array[8], "");
static_assert(__builtin_align_up(&align32array[7], 4) == &align32array[8], "");
static_assert(__builtin_align_up(&align32array[8], 4) == &align32array[8], "");
static_assert(__builtin_align_down(&align32array[0], 4) == &align32array[0], "");
static_assert(__builtin_align_down(&align32array[1], 4) == &align32array[0], "");
static_assert(__builtin_align_down(&align32array[2], 4) == &align32array[0], "");
static_assert(__builtin_align_down(&align32array[3], 4) == &align32array[0], "");
static_assert(__builtin_align_down(&align32array[4], 4) == &align32array[4], "");
static_assert(__builtin_align_down(&align32array[5], 4) == &align32array[4], "");
static_assert(__builtin_align_down(&align32array[6], 4) == &align32array[4], "");
static_assert(__builtin_align_down(&align32array[7], 4) == &align32array[4], "");
static_assert(__builtin_align_down(&align32array[8], 4) == &align32array[8], "");
static_assert((char *)((__UINTPTR_TYPE__)&align32array[7] & ~3) == &align32array[4], "");
static_assert(__builtin_align_down(&align32array[1], 4) == &align32array[0], "");
static_assert(__builtin_align_down(&align32array[1], 64) == &align32array[0], "");
static_assert(__builtin_is_aligned(&align32array[0], 32), "");
static_assert(__builtin_is_aligned(&align32array[4], 4), "");
static_assert(!__builtin_is_aligned(&align32array[0], 64), "");
static_assert(__builtin_is_aligned(&align32array[0], 4), "");
static_assert(!__builtin_is_aligned(&align32array[1], 4), "");
static_assert(!__builtin_is_aligned(&align32array[2], 4), "");
static_assert(!__builtin_is_aligned(&align32array[3], 4), "");
static_assert(__builtin_is_aligned(&align32array[4], 4), "");
static_assert(__builtin_is_aligned(__builtin_align_up(&align32array[0], 64), 64), "");
static_assert(!__builtin_is_aligned(static_cast<signed long>(7), static_cast<signed short>(4)), "");
static_assert(!__builtin_is_aligned(static_cast<signed short>(7), static_cast<signed long>(4)), "");
static_assert(!__builtin_is_aligned(static_cast<signed long>(7), static_cast<signed long>(4)), "");
static_assert(!__builtin_is_aligned(static_cast<unsigned long>(7), static_cast<unsigned long>(4)), "");
static_assert(!__builtin_is_aligned(static_cast<signed long>(7), static_cast<unsigned long>(4)), "");
static_assert(!__builtin_is_aligned(static_cast<unsigned long>(7), static_cast<signed long>(4)), "");
static_assert(!__builtin_is_aligned(static_cast<signed long>(7), static_cast<unsigned short>(4)), "");
static_assert(!__builtin_is_aligned(static_cast<unsigned short>(7), static_cast<signed long>(4)), "");