On Thu, Aug 22, 2013 at 11:16 AM, Jan Hubicka <hubi...@ucw.cz> wrote:
>> On Thu, Aug 22, 2013 at 10:39 AM, Jan Hubicka <hubi...@ucw.cz> wrote:
>> >> >
>> >> > So the existing program needs to overwrite libsup++ symbol like we do 
>> >> > with malloc?
>> >> > Of course with user defineed malloc function we should not propagate 
>> >> > the attribute,
>> >> > but I think we could have it when we end up calling the runtime.
>> >>
>> >> I suspect the question is whether our current infrastructure permits
>> >> to distinguish
>> >> between declaration of 'operator new' we supply, and 'operator new' 
>> >> defined by
>> >> user.  The way we currently arrange for user-defined 'operator new' to 
>> >> take
>> >> over is that it is something that is done at linktime, (so is LTO
>> >> prepared for this?)
>> >
>> > I think so (I am not expert though :))
>> > The operator new we supply is called _Znwm and I want the particular decl 
>> > with
>> > assembler name _Znwm to have malloc attribute.  I get it right, it is the
>> > declaration we build by
>> >
>> >     newtype = cp_build_type_attribute_variant (ptr_ftype_sizetype, 
>> > newattrs);
>> >     newtype = build_exception_variant (newtype, new_eh_spec);
>> >     deltype = cp_build_type_attribute_variant (void_ftype_ptr, extvisattr);
>> >     deltype = build_exception_variant (deltype, empty_except_spec);
>> >
>> >     push_cp_library_fn (NEW_EXPR, newtype);
>> >     push_cp_library_fn (VEC_NEW_EXPR, newtype);
>> >
>> > User's new will be different declarations with different assembler name. 
>> > It is
>> > up to user to care about malloc attributes or whatever.
>>
>> For functions that are replaceable, what counts is the provenance of the
>> *definition*, not just of one its declarations.  The sequence of code that 
>> you
>> show is mandated by C++.  Quoting C++11 3.7.4/2
>>
>>    The library provides default definitions for the global allocation and
>>    deallocation functions. Some global allocation and deallocation functions
>>    are replaceable (18.6.1). A C++ program shall provide at most one
>>    definition of a replaceable allocation or deallocation function. Any such
>>    function definition replaces the default version provided in the
>> library (17.6.4.6).
>>    The following allocation and deallocation functions (18.6) are implicitly
>>    declared in global scope in each translation unit of a program.
>
> This is quite unfortunate.   Thre is nothing standard promise about return
> value if this default new?

Oh, sure, there is.  Again, I am advocating *caution* (in order to support
existing idioms); I am not advocating against.  Concretely, that means we
need to refine your original proposal.  My previous analysis and suggestion
for LTO to be provenance-aware were made in that sense.

> I.e. can I have something like
>
> int a;
> test()
> {
>   int *b=new (int);
> }
>
> with custom implementation of new that returns &a?

If the user-supplied operator new returns &a, then it must
also ensure that 'a' is not used anywhere else -- e.g. I you can't
do lvalue-to-value conversion on 'a' to see what is written there.
Because its storage has been reused.  That is, aliasing is framed
in terms of object lifetime and uniqueness of ownership.

> While compiling given object file we do not know if the user program happens 
> to
> define it somewhere else or not.  Even with LTO I do not think we have
> mechanism to recognize statically or dynamically linked libsupc++ (we would
> have to LTO _Zwnm that will need to stabilize LTO format to start with).

Can we augment _DECLs and LTO to be provenance-aware?   For example,
in libstdc++ we already have pragmas saying that we are in a "system header"
so we don't warn about certain constructs there.  I'm sure my fellow libstdc++
maintainers could be convinced to add a pragma "system implementation" to
implementation files if they are assured that there are tangible
benefits to ripple
from doing that.

There are lot of opportunities for optimizing C++ programs if we can
do that, because
the standard library adds certain restrictions and make certain semantics
guarantees that we can't always expect from arbitrary user program fragments.

> We probably can go with -fno-user-overwritten-new or something similar?

-fno-user-supplied-allocation-function is possible but this is such a particular
case of a huge opportunity that it would be pity if we could just go
the extra mile.

-- Gaby

Reply via email to