Re: Improvement of CLOBBER descriptions

2024-02-22 Thread Jason Merrill via Gcc

On 2/21/24 10:43, Michael Matz wrote:

Hello,

On Wed, 21 Feb 2024, Daniil Frolov wrote:


Following the recent introduction of more detailed CLOBBER types in GCC, a
minor inconsistency has been identified in the description of
CLOBBER_OBJECT_BEGIN:

   /* Beginning of object lifetime, e.g. C++ constructor.  */
   CLOBBER_OBJECT_BEGIN


The "e.g." comment mixes concepts of the C++ language with a
middle-end/GIMPLE concept, and hence is a bit misleading.  What the
clobbers are intended to convey to the middle-end is the low-level notion
of "storage associated with this and that object is now accessible
(BEGIN)/not accessible anymore (END), for purposes related to that very
object".  The underlying motivation, _why_ that knowledge is interesting
to the middle-end, is to be able to share storage between different
objects.

"purposes related to that object" are any operations on the object:
construction, destruction, access, frobnification.  It's not tied to a
particular frontend language (although it's the language semantics that
dictate when emitting the begin/end clobbers is appropriate).  For the
middle-end the C++ concept of construction/deconstruction are simply
modifications (conceptual or real) of the storage associated with an
object ("object" not in the C++ sense, but from a low-level perspective;
i.e. an "object" doesn't only exist after c++-construction, it comes into
existence before that, even if perhaps in an indeterminate/invalid state
from the frontends perspective).

Initially these clobbers were only emitted when decls went ouf of
scope, and so did have some relation to frontend language semantics
(although a fairly universal one, namely "scope").  The
C++ frontend then found further uses (e.g. after a dtor for an
object _ends_ it's storage can also be reused), and eventually we also
needed the BEGIN clobbers to convey the meaning of "now storage use for
object potentially starts, don't share it with any other object".

If certain frontends find use for more fine-grained definitions of
life-times, then further note kinds need to be invented for those
frontends use.  They likely won't have influence on the middle-end though
(perhaps for some sanitizers such new kinds might be useful?).  But the
current BEGIN/END clobbers need to continue to mark the outermost borders
of storage validity for an object.


Yes.  The current uses of CLOBBER_OBJECT_* also include the period of 
construction/destruction, and we should clarify that in the comment, 
including avoiding the word "lifetime".


Or perhaps they could just be CLOBBER_STORAGE_*, though that would also 
be imprecise, since in various cases the storage duration of an object 
can be longer than beginning of construction to end of destruction; if I 
repeatedly construct and destroy objects in the same storage, I would 
like to have clobbers to indicate the boundaries between them.


But still, I don't think it's useful to distinguish between the two: 
what we want is clobbers to indicate the beginning and end of the use of 
storage to represent a particular object.  We don't need a clobber to 
tell the middle-end when storage begins and ends, it can work that out 
for itself, based in part on when individual objects begin and end.


So, my inclination is to remove STORAGE_* in favor of OBJECT_* and 
adjust the misleading comments for the latter.


As Michael says, emitting a clobber at the end of the constructor or 
beginning of the destructor seems inappropriate, as all clobbers 
indicate that the target does not have a meaningful value at that point. 
 Probably better to use some front-end-local representation that gets 
discarded by genericize.


Jason



Re: Improvement of CLOBBER descriptions

2024-02-21 Thread Michael Matz via Gcc
Hello,

On Wed, 21 Feb 2024, Daniil Frolov wrote:

> >> Following the recent introduction of more detailed CLOBBER types in GCC, a
> >> minor
> >> inconsistency has been identified in the description of
> >> CLOBBER_OBJECT_BEGIN:
> >> 
> >>   /* Beginning of object lifetime, e.g. C++ constructor.  */
> >>   CLOBBER_OBJECT_BEGIN

The "e.g." comment mixes concepts of the C++ language with a 
middle-end/GIMPLE concept, and hence is a bit misleading.  What the 
clobbers are intended to convey to the middle-end is the low-level notion 
of "storage associated with this and that object is now accessible 
(BEGIN)/not accessible anymore (END), for purposes related to that very 
object".  The underlying motivation, _why_ that knowledge is interesting 
to the middle-end, is to be able to share storage between different 
objects.

"purposes related to that object" are any operations on the object: 
construction, destruction, access, frobnification.  It's not tied to a 
particular frontend language (although it's the language semantics that 
dictate when emitting the begin/end clobbers is appropriate).  For the 
middle-end the C++ concept of construction/deconstruction are simply 
modifications (conceptual or real) of the storage associated with an 
object ("object" not in the C++ sense, but from a low-level perspective; 
i.e. an "object" doesn't only exist after c++-construction, it comes into 
existence before that, even if perhaps in an indeterminate/invalid state 
from the frontends perspective).

Initially these clobbers were only emitted when decls went ouf of 
scope, and so did have some relation to frontend language semantics 
(although a fairly universal one, namely "scope").  The 
C++ frontend then found further uses (e.g. after a dtor for an 
object _ends_ it's storage can also be reused), and eventually we also 
needed the BEGIN clobbers to convey the meaning of "now storage use for 
object potentially starts, don't share it with any other object".

If certain frontends find use for more fine-grained definitions of 
life-times, then further note kinds need to be invented for those 
frontends use.  They likely won't have influence on the middle-end though 
(perhaps for some sanitizers such new kinds might be useful?).  But the 
current BEGIN/END clobbers need to continue to mark the outermost borders 
of storage validity for an object.


Ciao,
Michael.


Re: Improvement of CLOBBER descriptions

2024-02-21 Thread Daniil Frolov

On 2024-02-21 15:33, Nathaniel Shead wrote:

On Wed, Feb 21, 2024 at 03:02:55PM +0400, Daniil Frolov wrote:

Hi.

Following the recent introduction of more detailed CLOBBER types in 
GCC, a

minor
inconsistency has been identified in the description of
CLOBBER_OBJECT_BEGIN:

  /* Beginning of object lifetime, e.g. C++ constructor.  */
  CLOBBER_OBJECT_BEGIN

This comment appears somewhat contradictory, as according to the C++
standard,
an object's lifetime commences upon completion of its initialization:

> The lifetime of an object of type T begins when:
>   -- storage with the proper alignment and size for type T is obtained,
> and
>   -- its initialization (if any) is complete (including vacuous
> initialization)
etc.

However, GCC emits CLOBBERs of this type at the beginning of a 
constructor.




And similarly for CLOBBER_OBJECT_END; by the standard an object ends 
its

lifetime at the start of the destructor, while we emit this at the end
of the destructor call.


Oh, thanks. I forgot about this one.



However, both placements are useful. At least for constexpr, the 
current

meaning of CLOBBER_OBJECT_END is important to know when we can still
access members of a class undergoing construction or destruction (see
[class.cdtor] p1) since this isn't directly tied to the elifetime of 
the

containing object itself.


Yes, I agree this behavior is useful. I realized the same thing when I 
worked
with the patch for emitting Valgrind annotation: setting memory as 
undefined
after constructor is done (if CLOBBER_OBJECT_START would be placed 
there) would

provoke FP.



But I'm still working for GCC 15 on correctly handling "partially
constructed" objects in constexpr (e.g. PR109518), and having a version
of CLOBBER_OBJECT_BEGIN at the /end/ of the constructor to signal this
might be useful as due to splitting of non-constant initialisers this 
is

otherwise a little awkward to determine from the IR currently.

Does anybody have any ideas how to make this description more precise? 
 It'd

be
better to clearly define what an object's lifetime is at the GIMPLE 
IMHO.


So, given the above, I think CLOBBER_OBJECT_BEGIN is still a pretty 
good

name (though maybe not perfect?), but maybe the comment should say
something like "Beginning of object construction"? Or otherwise mention
that this is the start of the lifetime of either the object or its 
first

subobject.


Maybe I've not clearly understood what does 'object construction' mean, 
but I want
to mention that C++ constructor is not the only point when lifetime of 
an object
begins. There are few exceptions for unions and for std::allocator (in 
C++) so it

looks a bit hard for me to generalize.

---
With best regards,
Daniil



Yours,
Nathaniel.


---
With best regards,
Daniil


Re: Improvement of CLOBBER descriptions

2024-02-21 Thread Nathaniel Shead via Gcc
On Wed, Feb 21, 2024 at 03:02:55PM +0400, Daniil Frolov wrote:
> Hi.
> 
> Following the recent introduction of more detailed CLOBBER types in GCC, a
> minor
> inconsistency has been identified in the description of
> CLOBBER_OBJECT_BEGIN:
> 
>   /* Beginning of object lifetime, e.g. C++ constructor.  */
>   CLOBBER_OBJECT_BEGIN
> 
> This comment appears somewhat contradictory, as according to the C++
> standard,
> an object's lifetime commences upon completion of its initialization:
> 
> > The lifetime of an object of type T begins when:
> >   -- storage with the proper alignment and size for type T is obtained,
> > and
> >   -- its initialization (if any) is complete (including vacuous
> > initialization)
> etc.
> 
> However, GCC emits CLOBBERs of this type at the beginning of a constructor.
> 

And similarly for CLOBBER_OBJECT_END; by the standard an object ends its
lifetime at the start of the destructor, while we emit this at the end
of the destructor call.

However, both placements are useful. At least for constexpr, the current
meaning of CLOBBER_OBJECT_END is important to know when we can still
access members of a class undergoing construction or destruction (see
[class.cdtor] p1) since this isn't directly tied to the lifetime of the
containing object itself.

But I'm still working for GCC 15 on correctly handling "partially
constructed" objects in constexpr (e.g. PR109518), and having a version
of CLOBBER_OBJECT_BEGIN at the /end/ of the constructor to signal this
might be useful as due to splitting of non-constant initialisers this is
otherwise a little awkward to determine from the IR currently.

> Does anybody have any ideas how to make this description more precise?  It'd
> be
> better to clearly define what an object's lifetime is at the GIMPLE IMHO.

So, given the above, I think CLOBBER_OBJECT_BEGIN is still a pretty good
name (though maybe not perfect?), but maybe the comment should say
something like "Beginning of object construction"? Or otherwise mention
that this is the start of the lifetime of either the object or its first
subobject.

Yours,
Nathaniel.

> ---
> With best regards,
> Daniil


Improvement of CLOBBER descriptions

2024-02-21 Thread Daniil Frolov

Hi.

Following the recent introduction of more detailed CLOBBER types in GCC, 
a minor
inconsistency has been identified in the description of 
CLOBBER_OBJECT_BEGIN:


  /* Beginning of object lifetime, e.g. C++ constructor.  */
  CLOBBER_OBJECT_BEGIN

This comment appears somewhat contradictory, as according to the C++ 
standard,

an object's lifetime commences upon completion of its initialization:


The lifetime of an object of type T begins when:
  -- storage with the proper alignment and size for type T is obtained, 
and
  -- its initialization (if any) is complete (including vacuous 
initialization)

etc.

However, GCC emits CLOBBERs of this type at the beginning of a 
constructor.


Does anybody have any ideas how to make this description more precise?  
It'd be
better to clearly define what an object's lifetime is at the GIMPLE 
IMHO.


---
With best regards,
Daniil