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