diff --git a/lib/libc/common/source/stdlib/malloc.c b/lib/libc/common/source/stdlib/malloc.c index 02354cd194dc..50c688fa7f21 100644 --- a/lib/libc/common/source/stdlib/malloc.c +++ b/lib/libc/common/source/stdlib/malloc.c @@ -153,6 +153,27 @@ void *aligned_alloc(size_t alignment, size_t size) return ret; } +#ifdef CONFIG_GLIBCXX_LIBCPP + +/* + * GCC's libstdc++ may use this function instead of aligned_alloc due to a + * bug in the configuration for "newlib" environments (which includes picolibc). + * When toolchains including that bug fix can become a dependency for Zephyr, + * this work-around can be removed. + * + * Note that aligned_alloc isn't defined to work as a replacement for + * memalign as it requires that the size be a multiple of the alignment, + * while memalign does not. However, the aligned_alloc implementation here + * is just a wrapper around sys_heap_aligned_alloc which doesn't have that + * requirement and so can be used by memalign. + */ + +void *memalign(size_t alignment, size_t size) +{ + return aligned_alloc(alignment, size); +} +#endif + static int malloc_prepare(void) { void *heap_base = NULL; diff --git a/tests/lib/cpp/libcxx/prj.conf b/tests/lib/cpp/libcxx/prj.conf index 043fb1391b37..fff9acb3adca 100644 --- a/tests/lib/cpp/libcxx/prj.conf +++ b/tests/lib/cpp/libcxx/prj.conf @@ -2,4 +2,5 @@ CONFIG_CPP=y CONFIG_STD_CPP17=y CONFIG_ZTEST=y CONFIG_ZTEST_STACK_SIZE=5120 +CONFIG_COMMON_LIBC_MALLOC_ARENA_SIZE=32768 CONFIG_ZTEST_NEW_API=y diff --git a/tests/lib/cpp/libcxx/src/main.cpp b/tests/lib/cpp/libcxx/src/main.cpp index 3151aaae892d..d1d7d37af188 100644 --- a/tests/lib/cpp/libcxx/src/main.cpp +++ b/tests/lib/cpp/libcxx/src/main.cpp @@ -9,6 +9,7 @@ #include #include #include +#include BUILD_ASSERT(__cplusplus == 201703); @@ -95,6 +96,17 @@ ZTEST(libcxx_tests, test_exception) } #endif +struct ThreadStack +{ + K_KERNEL_STACK_MEMBER(threadStack, 1024) {}; +}; + +ZTEST(libcxx_tests, test_new_aligned) +{ + auto test_aligned = std::make_unique(); + zassert_not_null(test_aligned, "aligned allocation failed"); +} + static void *libcxx_tests_setup(void) { TC_PRINT("version %u\n", (uint32_t)__cplusplus);