Skip to content

Commit c5e12bb

Browse files
committed
libstdc++: Prefer posix_memalign for aligned-new [PR113258]
As described in PR libstdc++/113258 there are old versions of tcmalloc which replace malloc and related APIs, but do not repalce aligned_alloc because it didn't exist at the time they were released. This means that when operator new(size_t, align_val_t) uses aligned_alloc to obtain memory, it comes from libc's aligned_alloc not from tcmalloc. But when operator delete(void*, size_t, align_val_t) uses free to deallocate the memory, that goes to tcmalloc's replacement version of free, which doesn't know how to free it. If we give preference to the older posix_memalign instead of aligned_alloc then we're more likely to use a function that will be compatible with the replacement version of free. Because posix_memalign has been around for longer, it's more likely that old third-party malloc replacements will also replace posix_memalign alongside malloc and free. libstdc++-v3/ChangeLog: PR libstdc++/113258 * libsupc++/new_opa.cc: Prefer to use posix_memalign if available. (cherry picked from commit f50f2ef)
1 parent 3bdd80d commit c5e12bb

File tree

1 file changed

+15
-11
lines changed

1 file changed

+15
-11
lines changed

libstdc++-v3/libsupc++/new_opa.cc

+15-11
Original file line numberDiff line numberDiff line change
@@ -46,12 +46,12 @@ using std::bad_alloc;
4646
using std::size_t;
4747
extern "C"
4848
{
49-
# if _GLIBCXX_HAVE_ALIGNED_ALLOC
49+
# if _GLIBCXX_HAVE_POSIX_MEMALIGN
50+
void *posix_memalign(void **, size_t alignment, size_t size);
51+
# elif _GLIBCXX_HAVE_ALIGNED_ALLOC
5052
void *aligned_alloc(size_t alignment, size_t size);
5153
# elif _GLIBCXX_HAVE__ALIGNED_MALLOC
5254
void *_aligned_malloc(size_t size, size_t alignment);
53-
# elif _GLIBCXX_HAVE_POSIX_MEMALIGN
54-
void *posix_memalign(void **, size_t alignment, size_t size);
5555
# elif _GLIBCXX_HAVE_MEMALIGN
5656
void *memalign(size_t alignment, size_t size);
5757
# else
@@ -63,13 +63,10 @@ extern "C"
6363
#endif
6464

6565
namespace __gnu_cxx {
66-
#if _GLIBCXX_HAVE_ALIGNED_ALLOC
67-
using ::aligned_alloc;
68-
#elif _GLIBCXX_HAVE__ALIGNED_MALLOC
69-
static inline void*
70-
aligned_alloc (std::size_t al, std::size_t sz)
71-
{ return _aligned_malloc(sz, al); }
72-
#elif _GLIBCXX_HAVE_POSIX_MEMALIGN
66+
// Prefer posix_memalign if available, because it's older than aligned_alloc
67+
// and so more likely to be provided by replacement malloc libraries that
68+
// predate the addition of aligned_alloc. See PR libstdc++/113258.
69+
#if _GLIBCXX_HAVE_POSIX_MEMALIGN
7370
static inline void*
7471
aligned_alloc (std::size_t al, std::size_t sz)
7572
{
@@ -83,6 +80,12 @@ aligned_alloc (std::size_t al, std::size_t sz)
8380
return ptr;
8481
return nullptr;
8582
}
83+
#elif _GLIBCXX_HAVE_ALIGNED_ALLOC
84+
using ::aligned_alloc;
85+
#elif _GLIBCXX_HAVE__ALIGNED_MALLOC
86+
static inline void*
87+
aligned_alloc (std::size_t al, std::size_t sz)
88+
{ return _aligned_malloc(sz, al); }
8689
#elif _GLIBCXX_HAVE_MEMALIGN
8790
static inline void*
8891
aligned_alloc (std::size_t al, std::size_t sz)
@@ -128,7 +131,8 @@ operator new (std::size_t sz, std::align_val_t al)
128131
if (__builtin_expect (sz == 0, false))
129132
sz = 1;
130133

131-
#if _GLIBCXX_HAVE_ALIGNED_ALLOC
134+
#if _GLIBCXX_HAVE_POSIX_MEMALIGN
135+
#elif _GLIBCXX_HAVE_ALIGNED_ALLOC
132136
# if defined _AIX || defined __APPLE__
133137
/* AIX 7.2.0.0 aligned_alloc incorrectly has posix_memalign's requirement
134138
* that alignment is a multiple of sizeof(void*).

0 commit comments

Comments
 (0)