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?

-- 
Regards,
    Mikhail Maltsev

Reply via email to