https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91369
--- Comment #15 from Jonathan Wakely <redi at gcc dot gnu.org> --- That's not valid, because operator new is not a constexpr function. You have to use a new-expression (that resolves to one of the standard operator new allocation functions), or std::allocator<T>::allocate, or std::allocator_traits<std::allocator<T>>::allocate. The result of std::allocator<T>::allocate can't be dereferenced until you've constructed an object there (and attempting to do so in a constexpr function should be ill-formed). This should work: constexpr int bar () { auto a = new int; // obtain storage for an int and begin its lifetime *a = 1; *a = *a + 2; int r = *a; delete a; // end lifetime and release storage return r; } constexpr auto p = bar (); And this: constexpr int baz () { auto a = std::allocator<int>::allocate(1); // obtain storage for an int std::construct_at(a); // begin lifetime of an int *a = 1; *a = *a + 2; int r = *a; std::destroy_at(a); // end lifetime std::allocator<int>::deallocate(a, 1); // release storage return r; } constexpr auto q = baz (); And the equivalent using std::allocator_traits: constexpr int baz2 () { std::allocator<int> alloc; using A = std::allocator_traits<std::allocator<int>>; auto a = A::allocate(alloc, 1); // obtain storage for an int A::construct(a); // calls std::construct_at *a = 1; *a = *a + 2; int r = *a; A::destroy(alloc, a); // calls std::destroy_at A::deallocate(alloc, a, 1); // release storage return r; } constexpr auto q = baz2 ();