[libcxx] r284206 - Implement P0035R4 -- Add C++17 aligned allocation functions
Eric Fiselier via cfe-commits
cfe-commits at lists.llvm.org
Thu Oct 13 23:46:31 PDT 2016
Author: ericwf
Date: Fri Oct 14 01:46:30 2016
New Revision: 284206
URL: http://llvm.org/viewvc/llvm-project?rev=284206&view=rev
Log:
Implement P0035R4 -- Add C++17 aligned allocation functions
Summary:
This patch implements the library side of P0035R4. The implementation is thanks to @rsmith.
In addition to the C++17 implementation, the library implementation can be explicitly turned on using `-faligned-allocation` in all dialects.
Reviewers: mclow.lists, rsmith
Subscribers: rsmith, cfe-commits
Differential Revision: https://reviews.llvm.org/D25591
Added:
libcxx/trunk/test/libcxx/language.support/support.dynamic/new_faligned_allocation.sh.cpp
libcxx/trunk/test/std/language.support/support.dynamic/align_val_t.pass.cpp
libcxx/trunk/test/std/language.support/support.dynamic/new.delete/new.delete.array/delete_align_val_t_replace.pass.cpp
libcxx/trunk/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_align_val_t.pass.cpp
libcxx/trunk/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_align_val_t_nothrow.pass.cpp
libcxx/trunk/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_align_val_t_nothrow_replace.pass.cpp
libcxx/trunk/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_align_val_t_replace.pass.cpp
libcxx/trunk/test/std/language.support/support.dynamic/new.delete/new.delete.single/delete_align_val_t_replace.pass.cpp
libcxx/trunk/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_align_val_t.pass.cpp
libcxx/trunk/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_align_val_t_nothrow.pass.cpp
libcxx/trunk/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_align_val_t_nothrow_replace.pass.cpp
libcxx/trunk/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_align_val_t_replace.pass.cpp
Modified:
libcxx/trunk/include/new
libcxx/trunk/lib/abi/CHANGELOG.TXT
libcxx/trunk/lib/abi/x86_64-linux-gnu.abilist
libcxx/trunk/src/new.cpp
libcxx/trunk/test/libcxx/test/config.py
Modified: libcxx/trunk/include/new
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/new?rev=284206&r1=284205&r2=284206&view=diff
==============================================================================
--- libcxx/trunk/include/new (original)
+++ libcxx/trunk/include/new Fri Oct 14 01:46:30 2016
@@ -27,18 +27,19 @@ public:
virtual const char* what() const noexcept;
};
-class bad_array_length : public bad_alloc // C++14
+class bad_array_length : public bad_alloc // FIXME: Not part of C++
{
public:
bad_array_length() noexcept;
};
-class bad_array_new_length : public bad_alloc
+class bad_array_new_length : public bad_alloc // C++14
{
public:
bad_array_new_length() noexcept;
};
+enum class align_val_t : size_t {}; // C++17
struct nothrow_t {};
extern const nothrow_t nothrow;
typedef void (*new_handler)();
@@ -48,16 +49,34 @@ new_handler get_new_handler() noexcept;
} // std
void* operator new(std::size_t size); // replaceable
+void* operator new(std::size_t size, std::align_val_t alignment); // replaceable, C++17
void* operator new(std::size_t size, const std::nothrow_t&) noexcept; // replaceable
+void* operator new(std::size_t size, std::align_val_t alignment,
+ const std::nothrow_t&) noexcept; // replaceable, C++17
void operator delete(void* ptr) noexcept; // replaceable
void operator delete(void* ptr, std::size_t size) noexcept; // replaceable, C++14
+void operator delete(void* ptr, std::align_val_t alignment) noexcept; // replaceable, C++17
+void operator delete(void* ptr, std::size_t size,
+ std::align_val_t alignment) noexcept; // replaceable, C++17
void operator delete(void* ptr, const std::nothrow_t&) noexcept; // replaceable
+void operator delete(void* ptr, std:align_val_t alignment,
+ const std::nothrow_t&) noexcept; // replaceable, C++17
void* operator new[](std::size_t size); // replaceable
+void* operator new[](std::size_t size,
+ std::align_val_t alignment) noexcept; // replaceable, C++17
void* operator new[](std::size_t size, const std::nothrow_t&) noexcept; // replaceable
+void* operator new[](std::size_t size, std::align_val_t alignment,
+ const std::nothrow_t&) noexcept; // replaceable, C++17
void operator delete[](void* ptr) noexcept; // replaceable
void operator delete[](void* ptr, std::size_t size) noexcept; // replaceable, C++14
+void operator delete[](void* ptr,
+ std::align_val_t alignment) noexcept; // replaceable, C++17
+void operator delete[](void* ptr, std::size_t size,
+ std::align_val_t alignment) noexcept; // replaceable, C++17
void operator delete[](void* ptr, const std::nothrow_t&) noexcept; // replaceable
+void operator delete[](void* ptr, std::align_val_t alignment,
+ const std::nothrow_t&) noexcept; // replaceable, C++17
void* operator new (std::size_t size, void* ptr) noexcept;
void* operator new[](std::size_t size, void* ptr) noexcept;
@@ -79,6 +98,16 @@ void operator delete[](void* ptr, void*
#pragma GCC system_header
#endif
+#if !(defined(_LIBCPP_BUILDING_NEW) || _LIBCPP_STD_VER >= 14 || \
+ (defined(__cpp_sized_deallocation) && __cpp_sized_deallocation >= 201309))
+# define _LIBCPP_HAS_NO_SIZED_DEALLOCATION
+#endif
+
+#if !(defined(_LIBCPP_BUILDING_NEW) || _LIBCPP_STD_VER > 14 || \
+ (defined(__cpp_aligned_new) && __cpp_aligned_new >= 201606))
+# define _LIBCPP_HAS_NO_ALIGNED_ALLOCATION
+#endif
+
namespace std // purposefully not using versioning namespace
{
@@ -117,6 +146,14 @@ public:
#endif // defined(_LIBCPP_BUILDING_NEW) || (_LIBCPP_STD_VER > 11)
+#ifndef _LIBCPP_HAS_NO_ALIGNED_ALLOCATION
+#ifndef _LIBCPP_CXX03_LANG
+enum class _LIBCPP_ENUM_VIS align_val_t : size_t { };
+#else
+enum align_val_t { __zero = 0, __max = (size_t)-1 };
+#endif
+#endif
+
struct _LIBCPP_TYPE_VIS nothrow_t {};
extern _LIBCPP_FUNC_VIS const nothrow_t nothrow;
typedef void (*new_handler)();
@@ -131,32 +168,46 @@ _LIBCPP_FUNC_VIS new_handler get_new_han
# define _LIBCPP_NEW_DELETE_VIS _LIBCPP_FUNC_VIS
#endif
-_LIBCPP_NEW_DELETE_VIS void* operator new(std::size_t __sz)
#if !__has_feature(cxx_noexcept)
- throw(std::bad_alloc)
+#define _THROW_BAD_ALLOC throw(std::bad_alloc)
+#else
+#define _THROW_BAD_ALLOC
#endif
-;
+
+_LIBCPP_NEW_DELETE_VIS void* operator new(std::size_t __sz) _THROW_BAD_ALLOC;
_LIBCPP_NEW_DELETE_VIS void* operator new(std::size_t __sz, const std::nothrow_t&) _NOEXCEPT _NOALIAS;
_LIBCPP_NEW_DELETE_VIS void operator delete(void* __p) _NOEXCEPT;
_LIBCPP_NEW_DELETE_VIS void operator delete(void* __p, const std::nothrow_t&) _NOEXCEPT;
-#if defined(_LIBCPP_BUILDING_NEW) || _LIBCPP_STD_VER >= 14 || \
- (defined(__cpp_sized_deallocation) && __cpp_sized_deallocation >= 201309)
+#ifndef _LIBCPP_HAS_NO_SIZED_DEALLOCATION
_LIBCPP_NEW_DELETE_VIS void operator delete(void* __p, std::size_t __sz) _NOEXCEPT;
#endif
-_LIBCPP_NEW_DELETE_VIS void* operator new[](std::size_t __sz)
-#if !__has_feature(cxx_noexcept)
- throw(std::bad_alloc)
-#endif
-;
+_LIBCPP_NEW_DELETE_VIS void* operator new[](std::size_t __sz) _THROW_BAD_ALLOC;
_LIBCPP_NEW_DELETE_VIS void* operator new[](std::size_t __sz, const std::nothrow_t&) _NOEXCEPT _NOALIAS;
_LIBCPP_NEW_DELETE_VIS void operator delete[](void* __p) _NOEXCEPT;
_LIBCPP_NEW_DELETE_VIS void operator delete[](void* __p, const std::nothrow_t&) _NOEXCEPT;
-#if defined(_LIBCPP_BUILDING_NEW) || _LIBCPP_STD_VER >= 14 || \
- (defined(__cpp_sized_deallocation) && __cpp_sized_deallocation >= 201309)
+#ifdef _LIBCPP_HAS_NO_SIZED_DEALLOCATION
_LIBCPP_NEW_DELETE_VIS void operator delete[](void* __p, std::size_t __sz) _NOEXCEPT;
#endif
+#ifndef _LIBCPP_HAS_NO_ALIGNED_ALLOCATION
+_LIBCPP_NEW_DELETE_VIS void* operator new(std::size_t __sz, std::align_val_t) _THROW_BAD_ALLOC;
+_LIBCPP_NEW_DELETE_VIS void* operator new(std::size_t __sz, std::align_val_t, const std::nothrow_t&) _NOEXCEPT _NOALIAS;
+_LIBCPP_NEW_DELETE_VIS void operator delete(void* __p, std::align_val_t) _NOEXCEPT;
+_LIBCPP_NEW_DELETE_VIS void operator delete(void* __p, std::align_val_t, const std::nothrow_t&) _NOEXCEPT;
+#ifndef _LIBCPP_HAS_NO_SIZED_DEALLOCATION
+_LIBCPP_NEW_DELETE_VIS void operator delete(void* __p, std::size_t __sz, std::align_val_t) _NOEXCEPT;
+#endif
+
+_LIBCPP_NEW_DELETE_VIS void* operator new[](std::size_t __sz, std::align_val_t) _THROW_BAD_ALLOC;
+_LIBCPP_NEW_DELETE_VIS void* operator new[](std::size_t __sz, std::align_val_t, const std::nothrow_t&) _NOEXCEPT _NOALIAS;
+_LIBCPP_NEW_DELETE_VIS void operator delete[](void* __p, std::align_val_t) _NOEXCEPT;
+_LIBCPP_NEW_DELETE_VIS void operator delete[](void* __p, std::align_val_t, const std::nothrow_t&) _NOEXCEPT;
+#ifndef _LIBCPP_HAS_NO_SIZED_DEALLOCATION
+_LIBCPP_NEW_DELETE_VIS void operator delete[](void* __p, std::size_t __sz, std::align_val_t) _NOEXCEPT;
+#endif
+#endif
+
inline _LIBCPP_INLINE_VISIBILITY void* operator new (std::size_t, void* __p) _NOEXCEPT {return __p;}
inline _LIBCPP_INLINE_VISIBILITY void* operator new[](std::size_t, void* __p) _NOEXCEPT {return __p;}
inline _LIBCPP_INLINE_VISIBILITY void operator delete (void*, void*) _NOEXCEPT {}
Modified: libcxx/trunk/lib/abi/CHANGELOG.TXT
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/lib/abi/CHANGELOG.TXT?rev=284206&r1=284205&r2=284206&view=diff
==============================================================================
--- libcxx/trunk/lib/abi/CHANGELOG.TXT (original)
+++ libcxx/trunk/lib/abi/CHANGELOG.TXT Fri Oct 14 01:46:30 2016
@@ -16,6 +16,22 @@ New entries should be added directly bel
Version 4.0
-----------
+* rTBD - Implement C++17 aligned allocation in <new>
+
+ x86_64-linux-gnu
+ ----------------
+ Symbol added: posix_memalign at GLIBC_2.2.5
+ Symbol added: _ZdaPvSt11align_val_t
+ Symbol added: _ZdlPvSt11align_val_t
+ Symbol added: _ZnamSt11align_val_t
+ Symbol added: _ZdaPvmSt11align_val_t
+ Symbol added: _ZdlPvmSt11align_val_t
+ Symbol added: _ZdlPvSt11align_val_tRKSt9nothrow_t
+ Symbol added: _ZnwmSt11align_val_tRKSt9nothrow_t
+ Symbol added: _ZnamSt11align_val_tRKSt9nothrow_t
+ Symbol added: _ZdaPvSt11align_val_tRKSt9nothrow_t
+ Symbol added: _ZnwmSt11align_val_t
+
* r283980 - Implement C++17 <optional>
x86_64-linux-gnu
Modified: libcxx/trunk/lib/abi/x86_64-linux-gnu.abilist
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/lib/abi/x86_64-linux-gnu.abilist?rev=284206&r1=284205&r2=284206&view=diff
==============================================================================
--- libcxx/trunk/lib/abi/x86_64-linux-gnu.abilist (original)
+++ libcxx/trunk/lib/abi/x86_64-linux-gnu.abilist Fri Oct 14 01:46:30 2016
@@ -1874,14 +1874,24 @@
{'type': 'FUNC', 'name': '_ZTv0_n24_NSt3__19strstreamD1Ev'}
{'type': 'FUNC', 'name': '_ZdaPv'}
{'type': 'FUNC', 'name': '_ZdaPvRKSt9nothrow_t'}
+{'type': 'FUNC', 'name': '_ZdaPvSt11align_val_t'}
+{'type': 'FUNC', 'name': '_ZdaPvSt11align_val_tRKSt9nothrow_t'}
{'type': 'FUNC', 'name': '_ZdaPvm'}
+{'type': 'FUNC', 'name': '_ZdaPvmSt11align_val_t'}
{'type': 'FUNC', 'name': '_ZdlPv'}
{'type': 'FUNC', 'name': '_ZdlPvRKSt9nothrow_t'}
+{'type': 'FUNC', 'name': '_ZdlPvSt11align_val_t'}
+{'type': 'FUNC', 'name': '_ZdlPvSt11align_val_tRKSt9nothrow_t'}
{'type': 'FUNC', 'name': '_ZdlPvm'}
+{'type': 'FUNC', 'name': '_ZdlPvmSt11align_val_t'}
{'type': 'FUNC', 'name': '_Znam'}
{'type': 'FUNC', 'name': '_ZnamRKSt9nothrow_t'}
+{'type': 'FUNC', 'name': '_ZnamSt11align_val_t'}
+{'type': 'FUNC', 'name': '_ZnamSt11align_val_tRKSt9nothrow_t'}
{'type': 'FUNC', 'name': '_Znwm'}
{'type': 'FUNC', 'name': '_ZnwmRKSt9nothrow_t'}
+{'type': 'FUNC', 'name': '_ZnwmSt11align_val_t'}
+{'type': 'FUNC', 'name': '_ZnwmSt11align_val_tRKSt9nothrow_t'}
{'type': 'FUNC', 'name': '__assert_fail at GLIBC_2.2.5'}
{'type': 'FUNC', 'name': '__ctype_get_mb_cur_max at GLIBC_2.2.5'}
{'type': 'FUNC', 'name': '__cxa_allocate_exception'}
@@ -1943,6 +1953,7 @@
{'type': 'FUNC', 'name': 'nanosleep at GLIBC_2.2.5'}
{'type': 'FUNC', 'name': 'newlocale at GLIBC_2.3'}
{'type': 'FUNC', 'name': 'open at GLIBC_2.2.5'}
+{'type': 'FUNC', 'name': 'posix_memalign at GLIBC_2.2.5'}
{'type': 'FUNC', 'name': 'pthread_cond_broadcast at GLIBC_2.3.2'}
{'type': 'FUNC', 'name': 'pthread_cond_destroy at GLIBC_2.3.2'}
{'type': 'FUNC', 'name': 'pthread_cond_signal at GLIBC_2.3.2'}
Modified: libcxx/trunk/src/new.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/src/new.cpp?rev=284206&r1=284205&r2=284206&view=diff
==============================================================================
--- libcxx/trunk/src/new.cpp (original)
+++ libcxx/trunk/src/new.cpp Fri Oct 14 01:46:30 2016
@@ -39,10 +39,7 @@
_LIBCPP_WEAK _LIBCPP_NEW_DELETE_VIS
void *
-operator new(std::size_t size)
-#if !__has_feature(cxx_noexcept)
- throw(std::bad_alloc)
-#endif
+operator new(std::size_t size) _THROW_BAD_ALLOC
{
if (size == 0)
size = 1;
@@ -65,6 +62,34 @@ operator new(std::size_t size)
}
_LIBCPP_WEAK _LIBCPP_NEW_DELETE_VIS
+void *
+operator new(std::size_t size, std::align_val_t alignment) _THROW_BAD_ALLOC
+{
+ if (size == 0)
+ size = 1;
+ if (static_cast<size_t>(alignment) < sizeof(void*))
+ alignment = std::align_val_t(sizeof(void*));
+ void* p;
+ while (::posix_memalign(&p, static_cast<size_t>(alignment), size) != 0)
+ {
+ // If posix_memalign fails and there is a new_handler,
+ // call it to try free up memory.
+ std::new_handler nh = std::get_new_handler();
+ if (nh)
+ nh();
+ else {
+#ifndef _LIBCPP_NO_EXCEPTIONS
+ throw std::bad_alloc();
+#else
+ p = nullptr; // posix_memalign doesn't initialize 'p' on failure
+ break;
+#endif
+ }
+ }
+ return p;
+}
+
+_LIBCPP_WEAK _LIBCPP_NEW_DELETE_VIS
void*
operator new(size_t size, const std::nothrow_t&) _NOEXCEPT
{
@@ -85,16 +110,39 @@ operator new(size_t size, const std::not
_LIBCPP_WEAK _LIBCPP_NEW_DELETE_VIS
void*
-operator new[](size_t size)
-#if !__has_feature(cxx_noexcept)
- throw(std::bad_alloc)
-#endif
+operator new(size_t size, std::align_val_t alignment, const std::nothrow_t&) _NOEXCEPT
+{
+ void* p = 0;
+#ifndef _LIBCPP_NO_EXCEPTIONS
+ try
+ {
+#endif // _LIBCPP_NO_EXCEPTIONS
+ p = ::operator new(size, alignment);
+#ifndef _LIBCPP_NO_EXCEPTIONS
+ }
+ catch (...)
+ {
+ }
+#endif // _LIBCPP_NO_EXCEPTIONS
+ return p;
+}
+
+_LIBCPP_WEAK _LIBCPP_NEW_DELETE_VIS
+void*
+operator new[](size_t size) _THROW_BAD_ALLOC
{
return ::operator new(size);
}
_LIBCPP_WEAK _LIBCPP_NEW_DELETE_VIS
void*
+operator new[](size_t size, std::align_val_t alignment) _THROW_BAD_ALLOC
+{
+ return ::operator new(size, alignment);
+}
+
+_LIBCPP_WEAK _LIBCPP_NEW_DELETE_VIS
+void*
operator new[](size_t size, const std::nothrow_t&) _NOEXCEPT
{
void* p = 0;
@@ -113,6 +161,25 @@ operator new[](size_t size, const std::n
}
_LIBCPP_WEAK _LIBCPP_NEW_DELETE_VIS
+void*
+operator new[](size_t size, std::align_val_t alignment, const std::nothrow_t&) _NOEXCEPT
+{
+ void* p = 0;
+#ifndef _LIBCPP_NO_EXCEPTIONS
+ try
+ {
+#endif // _LIBCPP_NO_EXCEPTIONS
+ p = ::operator new[](size, alignment);
+#ifndef _LIBCPP_NO_EXCEPTIONS
+ }
+ catch (...)
+ {
+ }
+#endif // _LIBCPP_NO_EXCEPTIONS
+ return p;
+}
+
+_LIBCPP_WEAK _LIBCPP_NEW_DELETE_VIS
void
operator delete(void* ptr) _NOEXCEPT
{
@@ -122,6 +189,14 @@ operator delete(void* ptr) _NOEXCEPT
_LIBCPP_WEAK _LIBCPP_NEW_DELETE_VIS
void
+operator delete(void* ptr, std::align_val_t) _NOEXCEPT
+{
+ if (ptr)
+ ::free(ptr);
+}
+
+_LIBCPP_WEAK _LIBCPP_NEW_DELETE_VIS
+void
operator delete(void* ptr, const std::nothrow_t&) _NOEXCEPT
{
::operator delete(ptr);
@@ -129,6 +204,13 @@ operator delete(void* ptr, const std::no
_LIBCPP_WEAK _LIBCPP_NEW_DELETE_VIS
void
+operator delete(void* ptr, std::align_val_t alignment, const std::nothrow_t&) _NOEXCEPT
+{
+ ::operator delete(ptr, alignment);
+}
+
+_LIBCPP_WEAK _LIBCPP_NEW_DELETE_VIS
+void
operator delete(void* ptr, size_t) _NOEXCEPT
{
::operator delete(ptr);
@@ -136,6 +218,13 @@ operator delete(void* ptr, size_t) _NOEX
_LIBCPP_WEAK _LIBCPP_NEW_DELETE_VIS
void
+operator delete(void* ptr, size_t, std::align_val_t alignment) _NOEXCEPT
+{
+ ::operator delete(ptr, alignment);
+}
+
+_LIBCPP_WEAK _LIBCPP_NEW_DELETE_VIS
+void
operator delete[] (void* ptr) _NOEXCEPT
{
::operator delete(ptr);
@@ -143,6 +232,13 @@ operator delete[] (void* ptr) _NOEXCEPT
_LIBCPP_WEAK _LIBCPP_NEW_DELETE_VIS
void
+operator delete[] (void* ptr, std::align_val_t alignment) _NOEXCEPT
+{
+ ::operator delete(ptr, alignment);
+}
+
+_LIBCPP_WEAK _LIBCPP_NEW_DELETE_VIS
+void
operator delete[] (void* ptr, const std::nothrow_t&) _NOEXCEPT
{
::operator delete[](ptr);
@@ -150,11 +246,25 @@ operator delete[] (void* ptr, const std:
_LIBCPP_WEAK _LIBCPP_NEW_DELETE_VIS
void
+operator delete[] (void* ptr, std::align_val_t alignment, const std::nothrow_t&) _NOEXCEPT
+{
+ ::operator delete[](ptr, alignment);
+}
+
+_LIBCPP_WEAK _LIBCPP_NEW_DELETE_VIS
+void
operator delete[] (void* ptr, size_t) _NOEXCEPT
{
::operator delete[](ptr);
}
+_LIBCPP_WEAK _LIBCPP_NEW_DELETE_VIS
+void
+operator delete[] (void* ptr, size_t, std::align_val_t alignment) _NOEXCEPT
+{
+ ::operator delete[](ptr, alignment);
+}
+
#endif // !__GLIBCXX__
namespace std
Added: libcxx/trunk/test/libcxx/language.support/support.dynamic/new_faligned_allocation.sh.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/libcxx/language.support/support.dynamic/new_faligned_allocation.sh.cpp?rev=284206&view=auto
==============================================================================
--- libcxx/trunk/test/libcxx/language.support/support.dynamic/new_faligned_allocation.sh.cpp (added)
+++ libcxx/trunk/test/libcxx/language.support/support.dynamic/new_faligned_allocation.sh.cpp Fri Oct 14 01:46:30 2016
@@ -0,0 +1,77 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// test libc++'s implementation of align_val_t, and the relevent new/delete
+// overloads in all dialects when -faligned-allocation is present.
+
+// REQUIRES: -faligned-allocation
+
+// RUN: %build -faligned-allocation
+// RUN: %run
+
+#include <new>
+#include <typeinfo>
+#include <string>
+#include <cassert>
+
+#include "test_macros.h"
+
+int main() {
+ {
+ static_assert(std::is_enum<std::align_val_t>::value, "");
+ typedef std::underlying_type<std::align_val_t>::type UT;
+ static_assert((std::is_same<UT, std::size_t>::value), "");
+ }
+ {
+ static_assert((!std::is_constructible<std::align_val_t, std::size_t>::value), "");
+#if TEST_STD_VER >= 11
+ static_assert(!std::is_constructible<std::size_t, std::align_val_t>::value, "");
+#else
+ static_assert((std::is_constructible<std::size_t, std::align_val_t>::value), "");
+#endif
+ }
+ {
+ std::align_val_t a = std::align_val_t(0);
+ std::align_val_t b = std::align_val_t(32);
+ assert(a != b);
+ assert(a == std::align_val_t(0));
+ assert(b == std::align_val_t(32));
+ }
+ {
+ void *ptr = ::operator new(1, std::align_val_t(128));
+ assert(ptr);
+ assert(reinterpret_cast<std::uintptr_t>(ptr) % 128 == 0);
+ ::operator delete(ptr, std::align_val_t(128));
+ }
+ {
+ void *ptr = ::operator new(1, std::align_val_t(128), std::nothrow);
+ assert(ptr);
+ assert(reinterpret_cast<std::uintptr_t>(ptr) % 128 == 0);
+ ::operator delete(ptr, std::align_val_t(128), std::nothrow);
+ }
+ {
+ void *ptr = ::operator new[](1, std::align_val_t(128));
+ assert(ptr);
+ assert(reinterpret_cast<std::uintptr_t>(ptr) % 128 == 0);
+ ::operator delete[](ptr, std::align_val_t(128));
+ }
+ {
+ void *ptr = ::operator new[](1, std::align_val_t(128), std::nothrow);
+ assert(ptr);
+ assert(reinterpret_cast<std::uintptr_t>(ptr) % 128 == 0);
+ ::operator delete[](ptr, std::align_val_t(128), std::nothrow);
+ }
+#ifndef TEST_HAS_NO_RTTI
+ {
+ // Check that libc++ doesn't define align_val_t in a versioning namespace.
+ // And that it mangles the same in C++03 through C++17
+ assert(typeid(std::align_val_t).name() == std::string("St11align_val_t"));
+ }
+#endif
+}
\ No newline at end of file
Modified: libcxx/trunk/test/libcxx/test/config.py
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/libcxx/test/config.py?rev=284206&r1=284205&r2=284206&view=diff
==============================================================================
--- libcxx/trunk/test/libcxx/test/config.py (original)
+++ libcxx/trunk/test/libcxx/test/config.py Fri Oct 14 01:46:30 2016
@@ -313,6 +313,9 @@ class Configuration(object):
if self.cxx.hasCompileFlag('-fsized-deallocation'):
self.config.available_features.add('fsized-deallocation')
+ if self.cxx.hasCompileFlag('-faligned-allocation'):
+ self.config.available_features.add('-faligned-allocation')
+
if self.get_lit_bool('has_libatomic', False):
self.config.available_features.add('libatomic')
Added: libcxx/trunk/test/std/language.support/support.dynamic/align_val_t.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/language.support/support.dynamic/align_val_t.pass.cpp?rev=284206&view=auto
==============================================================================
--- libcxx/trunk/test/std/language.support/support.dynamic/align_val_t.pass.cpp (added)
+++ libcxx/trunk/test/std/language.support/support.dynamic/align_val_t.pass.cpp Fri Oct 14 01:46:30 2016
@@ -0,0 +1,34 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// enum class align_val_t : size_t {}
+
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+
+#include <new>
+
+#include "test_macros.h"
+
+int main() {
+ {
+ static_assert(std::is_enum<std::align_val_t>::value, "");
+ static_assert(std::is_same<std::underlying_type<std::align_val_t>::type, std::size_t>::value, "");
+ static_assert(!std::is_constructible<std::align_val_t, std::size_t>::value, "");
+ static_assert(!std::is_constructible<std::size_t, std::align_val_t>::value, "");
+ }
+ {
+ constexpr auto a = std::align_val_t(0);
+ constexpr auto b = std::align_val_t(32);
+ constexpr auto c = std::align_val_t(-1);
+ static_assert(a != b, "");
+ static_assert(a == std::align_val_t(0), "");
+ static_assert(b == std::align_val_t(32), "");
+ static_assert(static_cast<std::size_t>(c) == (std::size_t)-1, "");
+ }
+}
\ No newline at end of file
Added: libcxx/trunk/test/std/language.support/support.dynamic/new.delete/new.delete.array/delete_align_val_t_replace.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/language.support/support.dynamic/new.delete/new.delete.array/delete_align_val_t_replace.pass.cpp?rev=284206&view=auto
==============================================================================
--- libcxx/trunk/test/std/language.support/support.dynamic/new.delete/new.delete.array/delete_align_val_t_replace.pass.cpp (added)
+++ libcxx/trunk/test/std/language.support/support.dynamic/new.delete/new.delete.array/delete_align_val_t_replace.pass.cpp Fri Oct 14 01:46:30 2016
@@ -0,0 +1,83 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// test aligned operator delete replacement.
+
+// UNSUPPORTED: sanitizer-new-delete, c++98, c++03, c++11, c++14
+
+// Older Clang versions do not support this
+// XFAIL: clang-3, apple-clang
+
+// None of the current GCC compilers support this.
+// XFAIL: gcc-4, gcc-5, gcc-6
+
+#include <new>
+#include <cstddef>
+#include <cstdlib>
+#include <cassert>
+
+constexpr auto OverAligned = alignof(std::max_align_t) * 2;
+
+int unsized_delete_called = 0;
+int unsized_delete_nothrow_called = 0;
+int aligned_delete_called = 0;
+
+void reset() {
+ unsized_delete_called = 0;
+ unsized_delete_nothrow_called = 0;
+ aligned_delete_called = 0;
+}
+
+void operator delete(void* p) throw()
+{
+ ++unsized_delete_called;
+ std::free(p);
+}
+
+void operator delete(void* p, const std::nothrow_t&) throw()
+{
+ ++unsized_delete_nothrow_called;
+ std::free(p);
+}
+
+void operator delete [] (void* p, std::align_val_t a) throw()
+{
+ ++aligned_delete_called;
+ std::free(p);
+}
+
+struct alignas(OverAligned) A {};
+struct alignas(std::max_align_t) B {};
+
+int main()
+{
+ {
+ B *x = new B;
+ assert(0 == unsized_delete_called);
+ assert(0 == unsized_delete_nothrow_called);
+ assert(0 == aligned_delete_called);
+
+ delete x;
+ assert(1 == unsized_delete_called);
+ assert(0 == unsized_delete_nothrow_called);
+ assert(0 == aligned_delete_called);
+ }
+ reset();
+ {
+ A *x = new A;
+ assert(0 == unsized_delete_called);
+ assert(0 == unsized_delete_nothrow_called);
+ assert(0 == aligned_delete_called);
+
+ delete x;
+ assert(0 == unsized_delete_called);
+ assert(0 == unsized_delete_nothrow_called);
+ assert(1 == aligned_delete_called);
+ }
+}
Added: libcxx/trunk/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_align_val_t.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_align_val_t.pass.cpp?rev=284206&view=auto
==============================================================================
--- libcxx/trunk/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_align_val_t.pass.cpp (added)
+++ libcxx/trunk/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_align_val_t.pass.cpp Fri Oct 14 01:46:30 2016
@@ -0,0 +1,77 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+
+// test operator new
+
+// asan and msan will not call the new handler.
+// UNSUPPORTED: sanitizer-new-delete
+
+#include <new>
+#include <cstddef>
+#include <cassert>
+#include <cstdint>
+#include <limits>
+
+#include "test_macros.h"
+
+constexpr auto OverAligned = alignof(std::max_align_t) * 2;
+
+int new_handler_called = 0;
+
+void new_handler()
+{
+ ++new_handler_called;
+ std::set_new_handler(0);
+}
+
+int A_constructed = 0;
+
+struct alignas(OverAligned) A
+{
+ A() { ++A_constructed;}
+ ~A() { --A_constructed;}
+};
+
+void test_throw_max_size() {
+#ifndef TEST_HAS_NO_EXCEPTIONS
+ std::set_new_handler(new_handler);
+ try
+ {
+ void* vp = operator new[] (std::numeric_limits<std::size_t>::max(),
+ static_cast<std::align_val_t>(32));
+ ((void)vp);
+ assert(false);
+ }
+ catch (std::bad_alloc&)
+ {
+ assert(new_handler_called == 1);
+ }
+ catch (...)
+ {
+ assert(false);
+ }
+#endif
+}
+
+int main()
+{
+ {
+ A* ap = new A[2];
+ assert(ap);
+ assert(reinterpret_cast<std::uintptr_t>(ap) % OverAligned == 0);
+ assert(A_constructed == 2);
+ delete [] ap;
+ assert(A_constructed == 0);
+ }
+ {
+ test_throw_max_size();
+ }
+}
Added: libcxx/trunk/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_align_val_t_nothrow.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_align_val_t_nothrow.pass.cpp?rev=284206&view=auto
==============================================================================
--- libcxx/trunk/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_align_val_t_nothrow.pass.cpp (added)
+++ libcxx/trunk/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_align_val_t_nothrow.pass.cpp Fri Oct 14 01:46:30 2016
@@ -0,0 +1,79 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+
+// test operator new (nothrow)
+
+// asan and msan will not call the new handler.
+// UNSUPPORTED: sanitizer-new-delete
+
+#include <new>
+#include <cstddef>
+#include <cstdint>
+#include <cassert>
+#include <limits>
+
+#include "test_macros.h"
+
+constexpr auto OverAligned = alignof(std::max_align_t) * 2;
+
+int new_handler_called = 0;
+
+void new_handler()
+{
+ ++new_handler_called;
+ std::set_new_handler(0);
+}
+
+int A_constructed = 0;
+
+struct alignas(OverAligned) A
+{
+ A() { ++A_constructed; }
+ ~A() { --A_constructed; }
+};
+
+void test_max_alloc() {
+ std::set_new_handler(new_handler);
+ auto do_test = []() {
+ void* vp = operator new [](std::numeric_limits<std::size_t>::max(),
+ std::align_val_t(OverAligned),
+ std::nothrow);
+ assert(new_handler_called == 1);
+ assert(vp == 0);
+ };
+#ifndef TEST_HAS_NO_EXCEPTIONS
+ try
+ {
+ do_test();
+ }
+ catch (...)
+ {
+ assert(false);
+ }
+#else
+ do_test();
+#endif
+}
+
+int main()
+{
+ {
+ A* ap = new(std::nothrow) A[3];
+ assert(ap);
+ assert(reinterpret_cast<std::uintptr_t>(ap) % OverAligned == 0);
+ assert(A_constructed == 3);
+ delete [] ap;
+ assert(!A_constructed);
+ }
+ {
+ test_max_alloc();
+ }
+}
Added: libcxx/trunk/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_align_val_t_nothrow_replace.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_align_val_t_nothrow_replace.pass.cpp?rev=284206&view=auto
==============================================================================
--- libcxx/trunk/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_align_val_t_nothrow_replace.pass.cpp (added)
+++ libcxx/trunk/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_align_val_t_nothrow_replace.pass.cpp Fri Oct 14 01:46:30 2016
@@ -0,0 +1,84 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+
+// test operator new nothrow by replacing only operator new
+
+// UNSUPPORTED: sanitizer-new-delete
+
+// TODO Investigate why UBSAN prevents nothrow new from calling our replacement.
+// XFAIL: ubsan
+
+#include <new>
+#include <cstddef>
+#include <cstdlib>
+#include <cassert>
+#include <limits>
+
+
+constexpr auto OverAligned = alignof(std::max_align_t) * 2;
+
+int A_constructed = 0;
+
+struct alignas(OverAligned) A
+{
+ A() {++A_constructed;}
+ ~A() {--A_constructed;}
+};
+
+int B_constructed = 0;
+
+struct B {
+ std::max_align_t member;
+ B() { ++B_constructed; }
+ ~B() { --B_constructed; }
+};
+
+int new_called = 0;
+alignas(OverAligned) char Buff[OverAligned * 3];
+
+void* operator new[](std::size_t s, std::align_val_t a) throw(std::bad_alloc)
+{
+ assert(!new_called);
+ assert(s <= sizeof(Buff));
+ assert(static_cast<std::size_t>(a) == OverAligned);
+ ++new_called;
+ return Buff;
+}
+
+void operator delete[](void* p, std::align_val_t a) throw()
+{
+ assert(p == Buff);
+ assert(static_cast<std::size_t>(a) == OverAligned);
+ assert(new_called);
+ --new_called;
+}
+
+int main()
+{
+ {
+ A* ap = new (std::nothrow) A[2];
+ assert(ap);
+ assert(A_constructed == 2);
+ assert(new_called);
+ delete [] ap;
+ assert(A_constructed == 0);
+ assert(!new_called);
+ }
+ {
+ B* bp = new (std::nothrow) B[2];
+ assert(bp);
+ assert(B_constructed == 2);
+ assert(!new_called);
+ delete [] bp;
+ assert(!new_called);
+ assert(!B_constructed);
+ }
+}
Added: libcxx/trunk/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_align_val_t_replace.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_align_val_t_replace.pass.cpp?rev=284206&view=auto
==============================================================================
--- libcxx/trunk/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_align_val_t_replace.pass.cpp (added)
+++ libcxx/trunk/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_align_val_t_replace.pass.cpp Fri Oct 14 01:46:30 2016
@@ -0,0 +1,82 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+
+// test operator new replacement
+
+// UNSUPPORTED: sanitizer-new-delete
+
+#include <new>
+#include <cstddef>
+#include <cstdlib>
+#include <cstdint>
+#include <cassert>
+#include <limits>
+
+constexpr auto OverAligned = alignof(std::max_align_t) * 2;
+
+int A_constructed = 0;
+
+struct alignas(OverAligned) A {
+ A() { ++A_constructed;}
+ ~A() { --A_constructed;}
+};
+
+
+int B_constructed = 0;
+
+struct alignas(std::max_align_t) B
+{
+ std::max_align_t member;
+ B() { ++B_constructed;}
+ ~B() { --B_constructed;}
+};
+
+int new_called = 0;
+
+alignas(OverAligned) char DummyData[OverAligned * 4];
+
+void* operator new[](std::size_t s, std::align_val_t a) throw(std::bad_alloc)
+{
+ assert(new_called == 0); // We already allocated
+ assert(s <= sizeof(DummyData));
+ assert(static_cast<std::size_t>(a) == OverAligned);
+ ++new_called;
+ return DummyData;
+}
+
+void operator delete[](void* p, std::align_val_t a) throw()
+{
+ assert(new_called == 1);
+ --new_called;
+ assert(p == DummyData);
+}
+
+
+int main()
+{
+ {
+ A* ap = new A[3];
+ assert(ap);
+ assert(A_constructed == 3);
+ assert(new_called);
+ delete [] ap;
+ assert(!A_constructed);
+ assert(!new_called);
+ }
+ {
+ B* bp = new B[3];
+ assert(bp);
+ assert(B_constructed == 3);
+ assert(!new_called);
+ delete [] bp;
+ assert(!new_called);
+ }
+}
Added: libcxx/trunk/test/std/language.support/support.dynamic/new.delete/new.delete.single/delete_align_val_t_replace.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/language.support/support.dynamic/new.delete/new.delete.single/delete_align_val_t_replace.pass.cpp?rev=284206&view=auto
==============================================================================
--- libcxx/trunk/test/std/language.support/support.dynamic/new.delete/new.delete.single/delete_align_val_t_replace.pass.cpp (added)
+++ libcxx/trunk/test/std/language.support/support.dynamic/new.delete/new.delete.single/delete_align_val_t_replace.pass.cpp Fri Oct 14 01:46:30 2016
@@ -0,0 +1,83 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// test aligned operator delete replacement.
+
+// UNSUPPORTED: sanitizer-new-delete, c++98, c++03, c++11, c++14
+
+// Older Clang versions do not support this
+// XFAIL: clang-3, apple-clang
+
+// None of the current GCC compilers support this.
+// XFAIL: gcc-4, gcc-5, gcc-6
+
+#include <new>
+#include <cstddef>
+#include <cstdlib>
+#include <cassert>
+
+constexpr auto OverAligned = alignof(std::max_align_t) * 2;
+
+int unsized_delete_called = 0;
+int unsized_delete_nothrow_called = 0;
+int aligned_delete_called = 0;
+
+void reset() {
+ unsized_delete_called = 0;
+ unsized_delete_nothrow_called = 0;
+ aligned_delete_called = 0;
+}
+
+void operator delete(void* p) throw()
+{
+ ++unsized_delete_called;
+ std::free(p);
+}
+
+void operator delete(void* p, const std::nothrow_t&) throw()
+{
+ ++unsized_delete_nothrow_called;
+ std::free(p);
+}
+
+void operator delete(void* p, std::align_val_t a) throw()
+{
+ ++aligned_delete_called;
+ std::free(p);
+}
+
+struct alignas(OverAligned) A {};
+struct alignas(std::max_align_t) B {};
+
+int main()
+{
+ {
+ B *x = new B;
+ assert(0 == unsized_delete_called);
+ assert(0 == unsized_delete_nothrow_called);
+ assert(0 == aligned_delete_called);
+
+ delete x;
+ assert(1 == unsized_delete_called);
+ assert(0 == unsized_delete_nothrow_called);
+ assert(0 == aligned_delete_called);
+ }
+ reset();
+ {
+ A *x = new A;
+ assert(0 == unsized_delete_called);
+ assert(0 == unsized_delete_nothrow_called);
+ assert(0 == aligned_delete_called);
+
+ delete x;
+ assert(0 == unsized_delete_called);
+ assert(0 == unsized_delete_nothrow_called);
+ assert(1 == aligned_delete_called);
+ }
+}
Added: libcxx/trunk/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_align_val_t.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_align_val_t.pass.cpp?rev=284206&view=auto
==============================================================================
--- libcxx/trunk/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_align_val_t.pass.cpp (added)
+++ libcxx/trunk/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_align_val_t.pass.cpp Fri Oct 14 01:46:30 2016
@@ -0,0 +1,77 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+
+// test operator new
+
+// asan and msan will not call the new handler.
+// UNSUPPORTED: sanitizer-new-delete
+
+#include <new>
+#include <cstddef>
+#include <cassert>
+#include <cstdint>
+#include <limits>
+
+#include "test_macros.h"
+
+constexpr auto OverAligned = alignof(std::max_align_t) * 2;
+
+int new_handler_called = 0;
+
+void new_handler()
+{
+ ++new_handler_called;
+ std::set_new_handler(0);
+}
+
+bool A_constructed = false;
+
+struct alignas(OverAligned) A
+{
+ A() {A_constructed = true;}
+ ~A() {A_constructed = false;}
+};
+
+void test_throw_max_size() {
+#ifndef TEST_HAS_NO_EXCEPTIONS
+ std::set_new_handler(new_handler);
+ try
+ {
+ void* vp = operator new (std::numeric_limits<std::size_t>::max(),
+ static_cast<std::align_val_t>(32));
+ ((void)vp);
+ assert(false);
+ }
+ catch (std::bad_alloc&)
+ {
+ assert(new_handler_called == 1);
+ }
+ catch (...)
+ {
+ assert(false);
+ }
+#endif
+}
+
+int main()
+{
+ {
+ A* ap = new A;
+ assert(ap);
+ assert(reinterpret_cast<std::uintptr_t>(ap) % OverAligned == 0);
+ assert(A_constructed);
+ delete ap;
+ assert(!A_constructed);
+ }
+ {
+ test_throw_max_size();
+ }
+}
Added: libcxx/trunk/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_align_val_t_nothrow.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_align_val_t_nothrow.pass.cpp?rev=284206&view=auto
==============================================================================
--- libcxx/trunk/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_align_val_t_nothrow.pass.cpp (added)
+++ libcxx/trunk/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_align_val_t_nothrow.pass.cpp Fri Oct 14 01:46:30 2016
@@ -0,0 +1,79 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+
+// test operator new (nothrow)
+
+// asan and msan will not call the new handler.
+// UNSUPPORTED: sanitizer-new-delete
+
+#include <new>
+#include <cstddef>
+#include <cstdint>
+#include <cassert>
+#include <limits>
+
+#include "test_macros.h"
+
+constexpr auto OverAligned = alignof(std::max_align_t) * 2;
+
+int new_handler_called = 0;
+
+void new_handler()
+{
+ ++new_handler_called;
+ std::set_new_handler(0);
+}
+
+bool A_constructed = false;
+
+struct alignas(OverAligned) A
+{
+ A() {A_constructed = true;}
+ ~A() {A_constructed = false;}
+};
+
+void test_max_alloc() {
+ std::set_new_handler(new_handler);
+ auto do_test = []() {
+ void* vp = operator new (std::numeric_limits<std::size_t>::max(),
+ std::align_val_t(OverAligned),
+ std::nothrow);
+ assert(new_handler_called == 1);
+ assert(vp == 0);
+ };
+#ifndef TEST_HAS_NO_EXCEPTIONS
+ try
+ {
+ do_test();
+ }
+ catch (...)
+ {
+ assert(false);
+ }
+#else
+ do_test();
+#endif
+}
+
+int main()
+{
+ {
+ A* ap = new(std::nothrow) A;
+ assert(ap);
+ assert(reinterpret_cast<std::uintptr_t>(ap) % OverAligned == 0);
+ assert(A_constructed);
+ delete ap;
+ assert(!A_constructed);
+ }
+ {
+ test_max_alloc();
+ }
+}
Added: libcxx/trunk/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_align_val_t_nothrow_replace.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_align_val_t_nothrow_replace.pass.cpp?rev=284206&view=auto
==============================================================================
--- libcxx/trunk/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_align_val_t_nothrow_replace.pass.cpp (added)
+++ libcxx/trunk/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_align_val_t_nothrow_replace.pass.cpp Fri Oct 14 01:46:30 2016
@@ -0,0 +1,85 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+
+// test operator new nothrow by replacing only operator new
+
+// UNSUPPORTED: sanitizer-new-delete
+
+// TODO Investigate why UBSAN prevents nothrow new from calling our replacement.
+// XFAIL: ubsan
+
+#include <new>
+#include <cstddef>
+#include <cstdlib>
+#include <cassert>
+#include <limits>
+
+
+constexpr auto OverAligned = alignof(std::max_align_t) * 2;
+
+bool A_constructed = false;
+
+struct alignas(OverAligned) A
+{
+ A() {A_constructed = true;}
+ ~A() {A_constructed = false;}
+};
+
+bool B_constructed = false;
+
+struct B {
+ std::max_align_t member;
+ B() { B_constructed = true; }
+ ~B() { B_constructed = false; }
+};
+
+int new_called = 0;
+alignas(OverAligned) char Buff[OverAligned * 2];
+
+void* operator new(std::size_t s, std::align_val_t a) throw(std::bad_alloc)
+{
+ assert(!new_called);
+ assert(s <= sizeof(Buff));
+ assert(static_cast<std::size_t>(a) == OverAligned);
+ ++new_called;
+ return Buff;
+}
+
+void operator delete(void* p, std::align_val_t a) throw()
+{
+ assert(p == Buff);
+ assert(static_cast<std::size_t>(a) == OverAligned);
+ assert(new_called);
+ --new_called;
+}
+
+
+int main()
+{
+ {
+ A* ap = new (std::nothrow) A;
+ assert(ap);
+ assert(A_constructed);
+ assert(new_called);
+ delete ap;
+ assert(!A_constructed);
+ assert(!new_called);
+ }
+ {
+ B* bp = new (std::nothrow) B;
+ assert(bp);
+ assert(B_constructed);
+ assert(!new_called);
+ delete bp;
+ assert(!new_called);
+ assert(!B_constructed);
+ }
+}
Added: libcxx/trunk/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_align_val_t_replace.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_align_val_t_replace.pass.cpp?rev=284206&view=auto
==============================================================================
--- libcxx/trunk/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_align_val_t_replace.pass.cpp (added)
+++ libcxx/trunk/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_align_val_t_replace.pass.cpp Fri Oct 14 01:46:30 2016
@@ -0,0 +1,82 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+
+// test operator new replacement
+
+// UNSUPPORTED: sanitizer-new-delete
+
+#include <new>
+#include <cstddef>
+#include <cstdlib>
+#include <cstdint>
+#include <cassert>
+#include <limits>
+
+constexpr auto OverAligned = alignof(std::max_align_t) * 2;
+
+bool A_constructed = false;
+
+struct alignas(OverAligned) A {
+ A() {A_constructed = true;}
+ ~A() {A_constructed = false;}
+};
+
+
+bool B_constructed = false;
+
+struct alignas(std::max_align_t) B
+{
+ std::max_align_t member;
+ B() {B_constructed = true;}
+ ~B() {B_constructed = false;}
+};
+
+int new_called = 0;
+
+alignas(OverAligned) char DummyData[OverAligned];
+
+void* operator new(std::size_t s, std::align_val_t a) throw(std::bad_alloc)
+{
+ assert(new_called == 0); // We already allocated
+ assert(s <= sizeof(DummyData));
+ assert(static_cast<std::size_t>(a) == OverAligned);
+ ++new_called;
+ return DummyData;
+}
+
+void operator delete(void* p, std::align_val_t a) throw()
+{
+ assert(new_called == 1);
+ --new_called;
+ assert(p == DummyData);
+}
+
+
+int main()
+{
+ {
+ A* ap = new A;
+ assert(ap);
+ assert(A_constructed);
+ assert(new_called);
+ delete ap;
+ assert(!A_constructed);
+ assert(!new_called);
+ }
+ {
+ B* bp = new B;
+ assert(bp);
+ assert(B_constructed);
+ assert(!new_called);
+ delete bp;
+ assert(!new_called);
+ }
+}
More information about the cfe-commits
mailing list