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