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.

Reply via email to