RFR (M): 8184334: Generalizing Atomic with templates
Andrew Haley
aph at redhat.com
Tue Jul 18 09:57:56 UTC 2017
On 18/07/17 10:38, Erik Österlund wrote:
>> ------------------------------------------------------------------------
>> 3.10, Lvalues and rvalues
>>
>> If a program attempts to access the stored value of an object through
>> a glvalue of other than one of the following types the behavior is
>> undefined:
>>
>> — the dynamic type of the object,
>>
>> — a cv-qualified version of the dynamic type of the object,
>>
>> — a type similar (as defined in 4.4) to the dynamic type of the object,
>>
>> — a type that is the signed or unsigned type corresponding to the
>> dynamic type of the object,
>>
>> — a type that is the signed or unsigned type corresponding to a
>> cv-qualified version of the dynamic type of the object,
>>
>> — an aggregate or union type that includes one of the aforementioned
>> types among its elements or non- static data members (including,
>> recursively, an element or non-static data member of a subaggregate
>> or contained union),
>>
>> — a type that is a (possibly cv-qualified) base class type of the
>> dynamic type of the object,
>>
>> — a char or unsigned char type.
>> ------------------------------------------------------------------------
>>
>> You only have permission to convert pointers to intptr_t and back: you
>> do not have permission to access the stored value of a pointer an an
>> intptr_t.
>
> I would say the scenario you describe goes under "the dynamic type of
> the object" or "a type that is the signed or unsigned type corresponding
> to the dynamic type of the object",
OK.
> in the quoted section 3.10 of the standard, depending on specific
> use case. The problem that type aliasing is aimed at is if you
> store an A* and then load it as a B*, then the dynamic type is A*,
> yet it is loaded as B*, where B is not compatible with A.
Precisely. That is what is happening in this case. A is, say, void*
and B is intptr_t. void* is not compatible with intptr_t.
> This is invariant of whether the value of the store is indirectly
> performed through intptr_t or loaded indirectly through intptr_t, as
> the dynamic type of the stored value is still A*.
Exactly so. The stored object is an A*. We're accessing it as an
intptr_t. A* and intptr_t are not compatible types. This is true
even if the intptr_t was the result of casting from an A*. The
compiler doesn't necessarily know that the intptr_t was originally an
A*: they might even be in separate compilation units. The compiler is
entitled to assume that the object in memory of type A* does not alias
with any value of type intptr_t.
> If you now perform a store of A* through Atomic that casts the pointer
> to intptr_t, and stores it, then the dynamic type is still A*.
This isn't how it works. (BTW, in case it helps understand where I'm
coming from, although I am not the greatest expert in this area, I am
familiar with GCC's alias analysis because I am a GCC author.)
> In summary, my point is that as long as the performed stores and loads
> in Atomic preserves the bit representation of whatever pointer was
> passed in, the dynamic type of that pointer is unchanged, invariantly of
> casting it to/from intptr_t, and hence the aliasing is allowed.
That is incorrect. Rules about aliasing are nothing to do with the
bit representation.
Let me reiterate: you may cast from any pointer type to intptr_t. You
may not access a pointer in memory as though it were an intptr_t.
--
Andrew Haley
Java Platform Lead Engineer
Red Hat UK Ltd. <https://www.redhat.com>
EAC8 43EB D3EF DB98 CC77 2FAD A5CD 6035 332F A671
More information about the hotspot-runtime-dev
mailing list