On Tue, Feb 03, 2026 at 08:00:53PM +0000, Jonathan Wakely wrote: > On Tue, 3 Feb 2026 at 19:57, Marek Polacek <[email protected]> wrote: > > > > On Tue, Feb 03, 2026 at 10:46:14AM +0000, Jonathan Wakely wrote: > > > On Mon, 2 Feb 2026 at 19:37, Marek Polacek <[email protected]> wrote: > > > > > > > > Bootstrapped/regtested on ppc64le-pc-linux-gnu, ok for trunk? > > > > > > > > -- >8 -- > > > > [allocator.members] says that allocator::{,de}allocate should be > > > > constexpr but currently we don't mark them as such. I had to > > > > > > We do mark std::allocator::allocate and deallocate, the ones you're > > > changing below are std::__new_allocator::allocate and > > > std::__new_allocator::deallocate, which should never be used during > > > constant eval: > > > > Aha. > > > > > include/bits/allocator.h has: > > > > > > #if __cplusplus > 201703L > > > [[nodiscard,__gnu__::__always_inline__]] > > > constexpr _Tp* > > > allocate(size_t __n) > > > { > > > if (std::__is_constant_evaluated()) > > > { > > > if (__builtin_mul_overflow(__n, sizeof(_Tp), &__n)) > > > std::__throw_bad_array_new_length(); > > > return static_cast<_Tp*>(::operator new(__n)); > > > } > > > > > > return __allocator_base<_Tp>::allocate(__n, 0); > > > } > > > > > > [[__gnu__::__always_inline__]] > > > constexpr void > > > deallocate(_Tp* __p, size_t __n) > > > { > > > if (std::__is_constant_evaluated()) > > > { > > > ::operator delete(__p); > > > return; > > > } > > > __allocator_base<_Tp>::deallocate(__p, __n); > > > } > > > #endif // C++20 > > > > > > > > > and __allocator_base is __new_allocator (for the default configure > > > flags anyway). > > > > > > So I'm surprised that the __new_allocator members need fixing. Why > > > does the reflection code ever end up looking at the __new_allocator > > > members? > > > > bases_of uses std::vector<info> so we instantiate > > > > constexpr _Tp* std::allocator<<...>::allocate(std::size_t) [with _Tp = > > std::meta::info; std::size_t = long unsigned int] > > > > which due to the "return __allocator_base<_Tp>::allocate(__n, 0)" > > instantiates > > > > _Tp* std::__new_allocator<_Tp>::allocate(size_type, const void*) [with > > _Tp = std::meta::info; size_type = long unsigned int] > > > > which has > > > > return static_cast<_Tp*>(_GLIBCXX_OPERATOR_NEW(__n * sizeof(_Tp))); > > > > in its body. _Tp is std::meta::info so we think this is a consteval-only > > expression, but std::__new_allocator::allocate isn't an "instantiation of > > a templated entity defined with the constexpr specifier" so we can't > > promote it to consteval so we error. With the added constexpr we can > > promote it to consteval and we don't error. > > > > Sorry that the original mail didn't explain this. > > Ah gotcha, so it's about instantiating it, not actually using it.
Yeah, the same problem happens even if I change if (std::__is_constant_evaluated()) to if (true) in std::allocator::allocate. > The library parts of the patch are fine then, thanks. Thanks! Marek
