New Clang flag "-fnew-infallible" to mark C++ new as "throw()" and "returns_nonnull"
Modi Mo
modimo@fb.com
Tue Aug 3 22:10:49 GMT 2021
On 8/3/21, 1:51 PM, "Jonathan Wakely" <jwakely.gcc@gmail.com> wrote:
>
> Could you explain this sentence in the commit message:
> "Note that the definition of global new is user-replaceable so users
> should ensure that the one used follows these semantics."
AFAICT based on the C++ standard, the user can replace the definition of operator new with anything they want.
In the current implementation we're using an un-enforced "throw()" annotation so it's up to the implementation of ::new (in libstdc++/jemalloc etc.) to comply properly or risk UB.
Marking ::new as noexcept is more rigid of an enforcement but I believe it's implementation defined as to how exception specifications are merged and because noexcept is not part of the mangled name link-time replacement would encounter the same issue.
> What happens if operator new does throw? Is that just treated like any
> other noexcept function that throws, i.e. std::terminate()? Or is it
> undefined behaviour?
It gets treated like the older "throw()" annotation where it's UB, there's no enforcement.
> And what if you use ::new(std::nothrow) and that fails, returning
> null. Is that undefined?
This change doesn't affect ::new(std::nothrow) ATM. Nathan Sidwell suggested that we may want to change semantics for non-throwing as well to be truly "infallible" but we don't have a use-case for this scenario as of yet.
> It seems to me that the former case (a potentially-throwing allocation
> function) could be turned into a std::terminate call fairly easily
> without losing the benefits of this option (you still know that no
> call to operator new will propagate exceptions).
Could you elaborate? That would be great if there's a way to do this without requiring enforcement on the allocator definition.
> But for the latter case the program *must* replace operator new to ensure that the
> nothrow form never returns null, otherwise you violate the promise
> that the returns_nonnull attribute makes, and have undefined
> behaivour. Is that right?
Yes good insight. That's another tricky aspect to implementing this for non-throwing new.
More information about the Gcc
mailing list