| // 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 %s -c -o %t.o |
| // RUN: linker cxx_11 %t.o -o %t%exeext |
| // RUN: runtool %t%exeext | grep "TEST PASSED" |
| |
| #include <stdio.h> |
| #include <new> |
| |
| // No cookie required for placement new |
| |
| #define BUFF_SIZE 1024 |
| #define ARRAY_LENGTH 5 |
| |
| // Globals |
| unsigned char alloc_buff[BUFF_SIZE]; |
| int new_calls = 0; |
| int delete_calls = 0; |
| |
| void *operator new[](size_t size) { new_calls++; return alloc_buff; } |
| void operator delete[](void *p) { delete_calls++; } |
| |
| struct non_trivial { |
| long long m1; |
| ~non_trivial() { } |
| }; |
| |
| struct array_cookie { |
| size_t element_count; |
| }; |
| |
| static int calculate_padding() { |
| return (sizeof(size_t) > alignof(non_trivial)) ? sizeof(size_t) : alignof(non_trivial); |
| } |
| |
| static int new_test() { |
| int errors = 0; |
| non_trivial *ptr = new non_trivial[ARRAY_LENGTH]; |
| |
| if((void *)ptr == (void *)alloc_buff) { |
| errors++; |
| printf("ERROR: new_test() pointers are equal!\n"); |
| } |
| |
| // Validate the cookie size |
| int padding = calculate_padding() - sizeof(array_cookie); |
| printf("padding is %d\n", padding); |
| if(((unsigned char *)alloc_buff + padding + sizeof(array_cookie)) != (unsigned char *)ptr) { |
| errors++; |
| printf("Cookie size incorrect (alloc_buff = 0x%p, ptr = 0x%p, padding = %d, sizeof(array_cookie) = %d)\n", alloc_buff, ptr, padding, sizeof(array_cookie)); |
| } |
| |
| // Validate the cookie contents |
| array_cookie *cookie = (array_cookie *)((unsigned char *)alloc_buff + 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; |
| non_trivial *ptr = new (alloc_buff) non_trivial[ARRAY_LENGTH]; |
| |
| if((void *)ptr != (void *)alloc_buff) { |
| errors++; |
| printf("ERROR: new_test() pointers differ!\n"); |
| } |
| |
| return errors; |
| } |
| |
| int main(int argc, char *argv[]) { |
| int retval = 0; |
| |
| retval += new_test(); |
| retval += placement_new_test(); |
| |
| if(retval) { |
| printf("TEST FAILED\n"); |
| retval = 1; |
| } else { |
| printf("TEST PASSED\n"); |
| retval = 0; |
| } |
| |
| return retval; |
| } |