[PATCH] D79378: PR34581: Don't remove an 'if (p)' guarding a call to 'operator delete(p)' under -Oz.

John McCall via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Fri Feb 3 12:57:34 PST 2023


rjmccall added a comment.

In D79378#4101935 <https://reviews.llvm.org/D79378#4101935>, @shiva0217 wrote:

> In D79378#4101829 <https://reviews.llvm.org/D79378#4101829>, @rjmccall wrote:
>
>> In D79378#4101613 <https://reviews.llvm.org/D79378#4101613>, @shiva0217 wrote:
>>
>>> Hi,
>>>
>>> I have a question for the delete function call sinking in -Oz.
>>>
>>> https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3690.pdf.
>>> According to 3.7.4.2/3
>>> ` The value of the first argument supplied to a deallocation function may be a null pointer value; if so, and if the deallocation function is one supplied in the standard library, the call has no effect. Otherwise, the behavior is undefined`
>>>
>>> It seems the null checking can be skipped only when the delete is not from the standard library(have been overloaded by the user), isn't it?
>>
>> The paragraph you just quoted says that the deallocation functions provided by the standard library are required have no effect on null pointers.  That means it's fine to call them with a null pointer even if the source wouldn't normally execute that call.  We could just insert these calls into random other code if we wanted to.
>
> Is a null operand of delete in the source code no effect because there will be null pointer checking generated?  Or the delete(null) in assembly code also valid?

In [expr.delete], the standard specifies that using the `delete` operator on a null pointer is required to have no effect.  It does not specify how that should be implemented.  In [basic.std.dynamic.deallocation], the standard also specifies that the library-provided `operator delete` functions must have no effect when given a null pointer.  This requirement applies no matter how the function is called, so yes, a call from assembly that passed a null pointer would also be required to have no effect.  More officially, you can simply take the address of `operator delete`, yielding an rvalue of `void (*)(void *)` (or similar, depending on which `operator delete` you use), which can then be called later in a context that doesn't understand it's calling a deallocation function; such a call is still required to have no effect when passing a null pointer, because the requirement is laid on the function, separate from the circumstances of it being called as part of the `delete` operator.

Note also that calling `operator delete` unconditionally when implementing the `delete` operator is explicitly blessed by [expr.delete]p7:

> If the value of the operand of the delete-expression is not a null pointer value, then:
>
>   ...
>
> Otherwise, it is unspecified whether the deallocation function will be called.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D79378/new/

https://reviews.llvm.org/D79378



More information about the llvm-commits mailing list