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