https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92143
Jonathan Wakely <redi at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Status|WAITING |ASSIGNED Assignee|unassigned at gcc dot gnu.org |redi at gcc dot gnu.org --- Comment #5 from Jonathan Wakely <redi at gcc dot gnu.org> --- Thanks for the checking the preprocessor output. (In reply to Daryl Haresign from comment #4) > C11 said: > > The aligned_alloc function allocates space for an object whose alignment is > specified by alignment, whose size is specified by size, and whose value is > indeterminate. The value of alignment shall be a valid alignment supported > by the implementation and the value of size shall be an integral multiple of > alignment. > > So it seems macOS and AIX's implementations are technically conformant. I disagree. The code in comment 2 makes two adjustments when we're using C11 aligned_alloc. The first one is specific to AIX, and increases the alignment to at least sizeof(void*): #if _GLIBCXX_HAVE_ALIGNED_ALLOC # ifdef _AIX /* AIX 7.2.0.0 aligned_alloc incorrectly has posix_memalign's requirement * that alignment is a multiple of sizeof(void*). */ if (align < sizeof(void*)) align = sizeof(void*); # endif This is *not* allowed by POSIX or C11. C11 6.2.8 says "Valid alignments include only those values returned by an _Alignof expression for fundamental types, plus an additional implementation-defined set of values, which may be empty. Every valid alignment shall be a nonnegative integral power of two." _Alignof(char) and _Alignof(short) and _Alignof(int) are valid alignments supported by the implementation, and so aligned_alloc is wrong to reject them. The second part of the code applies to all targets and makes the size adjustment required by C11: /* C11: the value of size shall be an integral multiple of alignment. */ sz = (sz + align - 1) & ~(align - 1); #endif > Perhaps GCC should determine whether the platform supports alignments less > than sizeof(void*) when GCC is built, and put a new macro in c++config.h > (assuming that's how that file is constructed)? That isn't necessarily possible because GCC could be built on a completely different system, so we can't run tests reliably. For this specific case I think the difference between using posix_memalign and aligned_alloc would not be ABI-breaking, so it would not be a problem if a native compiler used one and a cross-compiler used the other, but such a solution would mean the cross-compiler is still broken. So we need to add workarounds on a target-by-target basis anyway. The OS X man page does say: "In addition, aligned_alloc() returns a NULL pointer and sets errno to EINVAL if size is not an integral multiple of alignment, or if alignment is not a power of 2 at least as large as sizeof(void*)." So I'll extend the workaround to apply to OS X too.