blob: d90d0c8ae94082be9d53323d49202260f7efc271 [file] [log] [blame]
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
// RUN: cxx_compiler cxx_11 -c -o %t.o %s -DALIGN=1
// RUN: linker cxx_11 %t.o -o %t%exeext
// RUN: runtool %t%exeext | grep "TEST PASSED"
// RUN: cxx_compiler cxx_11 -c -o %t.o %s -DALIGN=2
// RUN: linker cxx_11 %t.o -o %t%exeext
// RUN: runtool %t%exeext | grep "TEST PASSED"
// RUN: cxx_compiler cxx_11 -c -o %t.o %s -DALIGN=4
// RUN: linker cxx_11 %t.o -o %t%exeext
// RUN: runtool %t%exeext | grep "TEST PASSED"
// RUN: cxx_compiler cxx_11 -c -o %t.o %s -DALIGN=8
// RUN: linker cxx_11 %t.o -o %t%exeext
// RUN: runtool %t%exeext | grep "TEST PASSED"
// RUN: cxx_compiler cxx_11 -c -o %t.o %s -DALIGN=16
// RUN: linker cxx_11 %t.o -o %t%exeext
// RUN: runtool %t%exeext | grep "TEST PASSED"
// RUN: cxx_compiler cxx_11 -c -o %t.o %s -DALIGN=32
// RUN: linker cxx_11 %t.o -o %t%exeext
// RUN: runtool %t%exeext | grep "TEST PASSED"
// RUN: cxx_compiler cxx_11 -c -o %t.o %s -DALIGN=64
// RUN: linker cxx_11 %t.o -o %t%exeext
// RUN: runtool %t%exeext | grep "TEST PASSED"
// RUN: cxx_compiler cxx_11 -c -o %t.o %s -DALIGN=128
// RUN: linker cxx_11 %t.o -o %t%exeext
// RUN: runtool %t%exeext | grep "TEST PASSED"
// RUN: cxx_compiler cxx_11 -c -o %t.o %s -DALIGN=256
// RUN: linker cxx_11 %t.o -o %t%exeext
// RUN: runtool %t%exeext | grep "TEST PASSED"
// RUN: cxx_compiler cxx_11 -c -o %t.o %s -DALIGN=512
// RUN: linker cxx_11 %t.o -o %t%exeext
// RUN: runtool %t%exeext | grep "TEST PASSED"
// RUN: cxx_compiler cxx_11 -c -o %t.o %s -DALIGN=1024
// RUN: linker cxx_11 %t.o -o %t%exeext
// RUN: runtool %t%exeext | grep "TEST PASSED"
// RUN: cxx_compiler cxx_11 -c -o %t.o %s -DALIGN=2048
// RUN: linker cxx_11 %t.o -o %t%exeext
// RUN: runtool %t%exeext | grep "TEST PASSED"
// RUN: cxx_compiler cxx_11 -c -o %t.o %s -DALIGN=4096
// RUN: linker cxx_11 %t.o -o %t%exeext
// RUN: runtool %t%exeext | grep "TEST PASSED"
// RUN: cxx_compiler cxx_11 -c -o %t.o %s -DALIGN=8192
// RUN: linker cxx_11 %t.o -o %t%exeext
// RUN: runtool %t%exeext | grep "TEST PASSED"
#include <stdio.h>
#include <stdlib.h>
#include <new>
// non-trivial struct with forced alignment test
#define ARRAY_LENGTH 5
#define BUFF_SIZE ALIGN * ARRAY_LENGTH * 2
// Globals
static unsigned char alloc_buff[BUFF_SIZE];
int new_calls = 0;
int delete_calls = 0;
static void *array_new_return_value;
void *operator new[](size_t size) {
new_calls++; return array_new_return_value = malloc(size);
}
#ifdef SKIP_STRONGLY_ALIGNED
// continue to use inline version because we need over-aligned result
inline void *operator new[](size_t size, size_t size2) {
new_calls++;
return array_new_return_value = alloc_buff;
}
#endif // SKIP_STRONGLY_ALIGNED
void operator delete[](void *p) { delete_calls++; }
static int verbose;
struct non_trivial {
~non_trivial() { }
} __attribute__((aligned(ALIGN)));
struct array_cookie {
size_t element_count;
};
static int calculate_padding() {
int size = (int) sizeof(size_t);
int alignment = alignof(non_trivial);
int retval = size > alignment ? size : alignment;
retval -= sizeof(array_cookie);
return (retval > 0 ? retval : 0);
}
static int new_test() {
int errors = 0;
non_trivial *ptr = new non_trivial[ARRAY_LENGTH];
if((void *)ptr == array_new_return_value) {
errors++;
printf("ERROR: new_test() pointers are equal!\n");
}
// Validate the cookie size
int padding = calculate_padding();
if(((unsigned char *)array_new_return_value + padding + sizeof(array_cookie)) != (unsigned char *)ptr) {
errors++;
printf("Cookie size incorrect (array_new_return_value = 0x%p, ptr = 0x%p, padding = %d, sizeof(array_cookie) = %d)\n", array_new_return_value, ptr, padding, (int) sizeof(array_cookie));
} else if (verbose)
printf("array_new_return_value = 0x%p, ptr = 0x%p, padding = %d, sizeof(array_cookie) = %d\n", array_new_return_value, ptr, padding, (int) sizeof(array_cookie));
// Validate the cookie contents
array_cookie *cookie = (array_cookie *)((unsigned char *)array_new_return_value + padding);
if(cookie->element_count != (size_t)ARRAY_LENGTH) {
errors++;
printf("Cookie value element_count incorrect, expected (%ld), got (%ld)\n", (size_t)ARRAY_LENGTH, cookie->element_count);
}
delete [] ptr;
return errors;
}
static int placement_new_test() {
int errors = 0;
#ifndef SKIP_STRONGLY_ALIGNED
non_trivial *ptr = new ((void*)alloc_buff) non_trivial[ARRAY_LENGTH];
if((void *)ptr != (void *)alloc_buff) {
errors++;
printf("ERROR: placement_new_test() pointers differ! %p != %p\n", ptr, array_new_return_value);
}
#endif // SKIP_STRONGLY_ALIGNED
return errors;
}
int main(int argc, char *argv[]) {
int retval = 0;
if (argc > 1) verbose = 1;
retval += new_test();
retval += placement_new_test();
if(retval) {
printf("TEST FAILED align=%d\n", ALIGN);
retval = 1;
} else {
printf("TEST PASSED align=%d\n", ALIGN);
retval = 0;
}
return retval;
}