Should pmr::memory_resource::allocate(n, a) use bit_ceil(a)?
Tomasz Kaminski
tkaminsk@redhat.com
Mon Jul 7 08:16:46 GMT 2025
On Fri, Jul 4, 2025 at 12:22 PM Jonathan Wakely <jwakely@redhat.com> wrote:
> On Fri, 4 Jul 2025 at 00:45, Jonathan Wakely <jwakely@redhat.com> wrote:
> >
> > On Fri, 4 Jul 2025 at 00:40, Jonathan Wakely <jwakely@redhat.com> wrote:
> > >
> > > I should probably adopt Martin's patch from
> > > https://gcc.gnu.org/PR86878 and finish it, so that we get warnings for
> > > invalid non-power-of-two alignments passed to allocation functions,
> > > but since we don't have that ...
> > >
> > > Would it be a good idea for pmr::memory_resource::allocate(n, a) to
> call:
> > > do_allocate(n, bit_ceil(a))
> > > ?
> > >
> > > That would ensure that the virtual override of do_allocate is always
> > > called with a valid alignment, even if the user violates the
> > > precondition of memory_resource::allocate.
> > >
> > > When the argument is a constant, the compiler can optimize bit_ceil(a)
> > > away if it knows it's already a power of two.
> > >
> > > Without this, I'm tempted to put an assertion or do the bit_ceil(a) in
> > > each override of do_allocate, to avoid potential UB caused by invalid
> > > alignment values.
> >
> > This would prevent a debugging memory resource from detecting invalid
> > alignments, because the derived type would always see valid
> > alignments. That would prevent such a resource from detecting bugs in
> > the program.
> >
> > But it would render such bugs harmless, which might be better for safety.
>
> Maybe the right compromise is for memory_resource::allocate to assert
> the precondition, and then our concrete do_allocate overrides in each
> derived memory_resource can use bit_ceil(a) if we want to defend
> against callers that disabled assertions and passed invalid
> alignments. That way user-defined resources could still potentially
> receive the invalid alignments (and throw bad_alloc or handle it
> however they want to).
>
> N.B. pmr::new_delete_resource()->do_allocate(n, a) just calls operator
> new(n, align_val_t(a)) and that throws bad_alloc for invalid
> alignments.
>
I think we should make the behavior of memory_resource::allocate erroneous
if the alignment is not a power of two, with calling do_allocatte(n,
bit_ceil(a))
as defined one.
I hope at some point erronous behavior will get some integration with
contracts,
like hardening. These are esentially precondition that are safe to run in
observe
or ignore mode, without triggering UB if they fail.
>
>
> >
> > Again, I should probably just implement the warning so that the
> > compiler detects those bugs (at least for cases where the requested
> > alignment is a constant).
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://gcc.gnu.org/pipermail/libstdc++/attachments/20250707/c3dc956b/attachment.htm>
More information about the Libstdc++
mailing list