Hmm, this seems to assume that operator delete itself doesn't do
anything with the object being deleted.  This is true of the default
implementation, but I don't see anything in the standard that
prohibits a user-supplied replacement or class-specific deallocation
function from accessing the memory.

Jason


On Mon, Apr 25, 2016 at 6:08 AM, Richard Biener
<richard.guent...@gmail.com> wrote:
> On Fri, Apr 22, 2016 at 11:37 PM, Mikhail Maltsev <malts...@gmail.com> wrote:
>> On 04/20/2016 05:12 PM, Richard Biener wrote:
>>> You have
>>>
>>> +static tree
>>> +handle_free_attribute (tree *node, tree name, tree /*args*/, int /*flags*/,
>>> +                      bool *no_add_attrs)
>>> +{
>>> +  tree decl = *node;
>>> +  if (TREE_CODE (decl) == FUNCTION_DECL
>>> +      && type_num_arguments (TREE_TYPE (decl)) != 0
>>> +      && POINTER_TYPE_P (TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (decl)))))
>>> +    DECL_ALLOC_FN_KIND (decl) = ALLOC_FN_FREE;
>>> +  else
>>> +    {
>>> +      warning_at (DECL_SOURCE_LOCATION (decl), OPT_Wattributes,
>>> +                 "%qE attribute ignored", name);
>>> +      *no_add_attrs = true;
>>> +    }
>>>
>>> so one can happily apply the attribute to
>>>
>>>  void foo (void *, void *);
>>>
>>> but then
>>>
>>> @@ -2117,6 +2127,13 @@ call_may_clobber_ref_p_1 (gcall *call, ao_ref *ref)
>>>           /* Fallthru to general call handling.  */;
>>>        }
>>>
>>> +  if (callee != NULL_TREE
>>> +      && (flags_from_decl_or_type (callee) & ECF_FREE) != 0)
>>> +    {
>>> +      tree ptr = gimple_call_arg (call, 0);
>>> +      return ptr_deref_may_alias_ref_p_1 (ptr, ref);
>>> +    }
>>>
>>> will ignore the 2nd argument.  I think it's better to ignore the attribute
>>> if type_num_arguments () != 1.
>>
>> Actually, the C++ standard ([basic.stc.dynamic]/2) defines the following 4
>> deallocation functions implicitly:
>>
>> void operator delete(void*);
>> void operator delete[](void*);
>> void operator delete(void*, std::size_t) noexcept;
>> void operator delete[](void*, std::size_t) noexcept;
>>
>> And the standard library also has:
>>
>> void operator delete(void*, const std::nothrow_t&);
>> void operator delete[](void*, const std::nothrow_t&);
>> void operator delete(void*, std::size_t, const std::nothrow_t&);
>> void operator delete[](void*, std::size_t, const std::nothrow_t&);
>>
>> IIUC, 'delete(void*, std::size_t)' is used by default in C++14
>> (https://gcc.gnu.org/ml/gcc-patches/2014-12/msg01266.html). How should we 
>> handle
>> this?
>
> Hmm.  I guess by adjusting the documentation of the attribute to
> explicitely mention
> the behavior on the rest of the argument pointed-to memory (the
> function is assumed
> to neither write nor read from that memory).  Also explicitely mention
> that 'this' is
> always the first argument if present.
>
> Richard.
>
>> --
>> Regards,
>>     Mikhail Maltsev

Reply via email to