Index: src/cxa_exception.cpp =================================================================== --- src/cxa_exception.cpp +++ src/cxa_exception.cpp @@ -65,12 +65,16 @@ return cxa_exception_from_thrown_object(unwind_exception + 1 ); } -static -inline -size_t -cxa_exception_size_from_exception_thrown_size(size_t size) -{ - return size + sizeof (__cxa_exception); +// Round s up to next multiple of a. +static inline +size_t aligned_allocation_size(size_t s, size_t a) { + return (s + a - 1) & ~(a - 1); +} + +static inline +size_t cxa_exception_size_from_exception_thrown_size(size_t size) { + return aligned_allocation_size(size + sizeof (__cxa_exception), + alignof(__cxa_exception)); } static void setExceptionClass(_Unwind_Exception* unwind_exception) { Index: src/fallback_malloc.cpp =================================================================== --- src/fallback_malloc.cpp +++ src/fallback_malloc.cpp @@ -196,11 +196,13 @@ #pragma GCC visibility push(hidden) +struct __attribute__((aligned)) __aligned_type {}; + void * __malloc_with_fallback(size_t size) { - void *ptr = std::malloc(size); - if (NULL == ptr) // if malloc fails, fall back to emergency stash - ptr = fallback_malloc(size); - return ptr; + void* dest; + if (::posix_memalign(&dest, alignof(__aligned_type), size) == 0) + return dest; + return fallback_malloc(size); } void * __calloc_with_fallback(size_t count, size_t size) { Index: test/test_exception_address_alignment.pass.cpp =================================================================== --- /dev/null +++ test/test_exception_address_alignment.pass.cpp @@ -0,0 +1,28 @@ +//===----------------------------------------------------------------------===// +// +// 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 that the address of the exception object is properly aligned to the +// largest supported alignment for the system. + +#include +#include + +struct __attribute__((aligned)) AlignedType {}; +struct MinAligned { }; +static_assert(alignof(MinAligned) == 1 && sizeof(MinAligned) == 1, ""); + +int main() { + for (int i=0; i < 10; ++i) { + try { + throw MinAligned{}; + } catch (MinAligned const& ref) { + assert(reinterpret_cast(&ref) % alignof(AlignedType) == 0); + } + } +}