From 1d1b732865a2dd3a97b8a8e605d7c5906ab0df0e Mon Sep 17 00:00:00 2001 From: Jonathan Wakely Date: Tue, 7 Aug 2018 17:10:29 +0100 Subject: [PATCH] PR libstdc++/86861 Meet precondition for Solaris memalign Solaris memalign requires alignment to be at least sizeof(int), so increase it as needed. Also move the check for valid alignments from the fallback implementation of aligned_alloc into operator new, as it's required for all of aligned_alloc, memalign, posix_memalign and __aligned_malloc. This adds a branch to check for undefined behaviour which we could just ignore, so the check could just be removed. It should certainly be removed if PR 86878 is implemented to issue a warning about calls with invalid alignments. PR libstdc++/86861 * libsupc++/new_opa.cc [_GLIBCXX_HAVE_MEMALIGN] (aligned_alloc): Replace macro with inline function. [__sun]: Increase alignment to meet memalign precondition. [!HAVE__ALIGNED_MALLOC && !HAVE_POSIX_MEMALIGN && !HAVE_MEMALIGN] (aligned_alloc): Move check for valid alignment to operator new. Remove redundant check for non-zero size, it's enforced by the caller. (operator new): Move check for valid alignment here. Use __builtin_expect on check for zero size. From-SVN: r263360 --- libstdc++-v3/ChangeLog | 10 ++++++++++ libstdc++-v3/libsupc++/new_opa.cc | 28 +++++++++++++++++++--------- 2 files changed, 29 insertions(+), 9 deletions(-) diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 5f098c87e40..ce410ed2e0d 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,5 +1,15 @@ 2018-08-07 Jonathan Wakely + PR libstdc++/86861 + * libsupc++/new_opa.cc [_GLIBCXX_HAVE_MEMALIGN] (aligned_alloc): + Replace macro with inline function. + [__sun]: Increase alignment to meet memalign precondition. + [!HAVE__ALIGNED_MALLOC && !HAVE_POSIX_MEMALIGN && !HAVE_MEMALIGN] + (aligned_alloc): Move check for valid alignment to operator new. + Remove redundant check for non-zero size, it's enforced by the caller. + (operator new): Move check for valid alignment here. Use + __builtin_expect on check for zero size. + * config/abi/pre/gnu.ver: Export monotonic_buffer_resource members. * include/std/memory_resource (monotonic_buffer_resource::release): Call _M_release_buffers to free buffers. diff --git a/libstdc++-v3/libsupc++/new_opa.cc b/libstdc++-v3/libsupc++/new_opa.cc index 7c4bb79cdab..5be0cc2ca65 100644 --- a/libstdc++-v3/libsupc++/new_opa.cc +++ b/libstdc++-v3/libsupc++/new_opa.cc @@ -39,6 +39,7 @@ static inline void* aligned_alloc (std::size_t al, std::size_t sz) { void *ptr; + // posix_memalign has additional requirement, not present on aligned_alloc: // The value of alignment shall be a power of two multiple of sizeof(void *). if (al < sizeof(void*)) al = sizeof(void*); @@ -53,20 +54,24 @@ aligned_alloc (std::size_t al, std::size_t sz) #else extern "C" void *memalign(std::size_t boundary, std::size_t size); #endif -#define aligned_alloc memalign -#else +static inline void* +aligned_alloc (std::size_t al, std::size_t sz) +{ +#ifdef __sun + // Solaris 10 memalign requires that alignment is greater than or equal to + // the size of a word. + if (al < sizeof(int)) + al = sizeof(int); +#endif + return memalign (al, sz); +} +#else // !HAVE__ALIGNED_MALLOC && !HAVE_POSIX_MEMALIGN && !HAVE_MEMALIGN #include // The C library doesn't provide any aligned allocation functions, define one. // This is a modified version of code from gcc/config/i386/gmm_malloc.h static inline void* aligned_alloc (std::size_t al, std::size_t sz) { - // Alignment must be a power of two. - if (al & (al - 1)) - return nullptr; - else if (!sz) - return nullptr; - // We need extra bytes to store the original value returned by malloc. if (al < sizeof(void*)) al = sizeof(void*); @@ -90,8 +95,13 @@ operator new (std::size_t sz, std::align_val_t al) void *p; std::size_t align = (std::size_t)al; + /* Alignment must be a power of two. */ + /* XXX This should be checked by the compiler (PR 86878). */ + if (__builtin_expect (align & (align - 1), false)) + _GLIBCXX_THROW_OR_ABORT(bad_alloc()); + /* malloc (0) is unpredictable; avoid it. */ - if (sz == 0) + if (__builtin_expect (sz == 0, false)) sz = 1; #if _GLIBCXX_HAVE_ALIGNED_ALLOC -- 2.30.2