https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90611
--- Comment #5 from Jonathan Wakely <redi at gcc dot gnu.org> ---
We could do this in std::allocator:
--- a/libstdc++-v3/include/ext/new_allocator.h
+++ b/libstdc++-v3/include/ext/new_allocator.h
@@ -110,6 +110,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
std::align_val_t __al = std::align_val_t(alignof(_Tp));
return static_cast<_Tp*>(::operator new(__n * sizeof(_Tp), __al));
}
+#elif __cplusplus >= 201103L
+ if (alignof(_Tp) > alignof(std::max_align_t))
+ __throw_bad_alloc();
#endif
return static_cast<_Tp*>(::operator new(__n * sizeof(_Tp)));
}
Which would mean std::allocator refuses to allocate memory for overaligned
types in C++11 and C++14 unless -faligned-new is enabled.
I tried issuing a warning instead:
--- a/libstdc++-v3/include/ext/new_allocator.h
+++ b/libstdc++-v3/include/ext/new_allocator.h
@@ -35,6 +35,7 @@
#include <bits/move.h>
#if __cplusplus >= 201103L
#include <type_traits>
+#include <cstddef>
#endif
namespace __gnu_cxx _GLIBCXX_VISIBILITY(default)
@@ -110,10 +111,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
std::align_val_t __al = std::align_val_t(alignof(_Tp));
return static_cast<_Tp*>(::operator new(__n * sizeof(_Tp), __al));
}
+#elif __cplusplus >= 201103L
+ if (alignof(_Tp) > alignof(std::max_align_t))
+ __overaligned();
#endif
return static_cast<_Tp*>(::operator new(__n * sizeof(_Tp)));
}
+ void __overaligned() __attribute__((__warning__("use -faligned-new to
enable support for overaligned types"))) { }
+
// __p is not permitted to be a null pointer.
void
deallocate(pointer __p, size_type __t)
But that warning is suppressed unless you use -Wsystem-headers.
Alternatively:
--- a/libstdc++-v3/include/ext/new_allocator.h
+++ b/libstdc++-v3/include/ext/new_allocator.h
@@ -35,6 +35,7 @@
#include <bits/move.h>
#if __cplusplus >= 201103L
#include <type_traits>
+#include <cstddef>
#endif
namespace __gnu_cxx _GLIBCXX_VISIBILITY(default)
@@ -110,6 +111,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
std::align_val_t __al = std::align_val_t(alignof(_Tp));
return static_cast<_Tp*>(::operator new(__n * sizeof(_Tp), __al));
}
+#elif __cplusplus >= 201103L
+ static_assert(alignof(_Tp) <= alignof(std::max_align_t),
+ "use -faligned-new to support allocation of overaligned types");
#endif
return static_cast<_Tp*>(::operator new(__n * sizeof(_Tp)));
}
But none of these would help for the original reproducer, because GCC 8 doesn't
think it's overaligned, because of the disagreement between max_align_t and
malloc.