<div>> But the pointer itself does constitute another separate object. And<br/>
that object is the one that is stored in the union (the uint8_t data is<br/>
not stored in the union, but in some other allocated memory (probably)).<br/>
<br/>
The pointer to structure's field does not stored in the structure. And reading the pointer to the field is just adding an offset to the object pointer.<br/>
<br/>
Why do you ignore my suggestion to replace "p->base" with "(uint8_t *) p" and try to understand the purpose of the object, 'base' and 'offset'? Instead you digging the specifications to prove the validation software behavior.<br/>
<br/>
--<br/>
Max<br/><br/>-----Original Message-----<br/>From: Alejandro Colomar <alx.manpages@gmail.com><br/>To: Max Romanov <max.romanov@gmail.com>, Andrew Clayton <andrew@digital-domain.net><br/>Cc: unit@nginx.org<br/>Sent: сб, 18 июн. 2022 2:15<br/>Subject: Re: [PATCH 06/11] Sptr: avoided potentially undefined behaviour.<br/><br/></div>Hi Max
<br/>
<br/>
On 6/18/22 01:04, Max Romanov wrote:
<br/>
> I'm sorry to be a pain,
<br/>
<br/>
No problem :)
<br/>
<br/>
but the key thing is: ".. read from another
<br/>
> object..".
<br/>
<br/>
In this case, ISO C uses the term object to refer to a broader concept,
<br/>
that includes any variable.
<br/>
<br/>
3.15/1,2:
<br/>
"
<br/>
object
<br/>
region of data storage in the execution environment, the contents of
<br/>
which can represent values
<br/>
"
<br/>
<br/>
> In the statement you are trying to "fix", the "base" does not
<br/>
> actually _read_ from the object (structure, to be precise), instead the
<br/>
> address of the structure itself used. In other words, "p->base" is a
<br/>
> shortcut for "(uint8_t *) p".
<br/>
<br/>
the region of data storage pointed to by `p->base` would be an object
<br/>
(of type uint8_t, or maybe uint8_t[]).
<br/>
<br/>
But the pointer itself does constitute another separate object. And
<br/>
that object is the one that is stored in the union (the uint8_t data is
<br/>
not stored in the union, but in some other allocated memory (probably)).
<br/>
<br/>
Since we are reading a member of the union (and each member is an
<br/>
object, by definition, even if it's a pointer), and storing the value
<br/>
into another member of the union, that's not valid.
<br/>
<br/>
As pointed by @supercat in StackOverflow (in the link I provided), the
<br/>
rationale was probably to allow compilers to do some optimizations, or
<br/>
for example, copy byte by byte; in archs where the union members are
<br/>
larger than a register, this will definitely cause a bug; in archs where
<br/>
the union members fit into a register (as in our case), the code is
<br/>
likely to work, but the standard makes no guarantees about it, and a
<br/>
compiler may still do bad stuff. It's better to be safe.
<br/>
<br/>
Cheers,
<br/>
<br/>
Alex
<br/>
>> <<a href="https://stackoverflow.com/a/72652427/6872717">https://stackoverflow.com/a/72652427/6872717</a>
<br/>
--
<br/>
Alejandro Colomar
<br/>
<<a href="http://www.alejandro-colomar.es">http://www.alejandro-colomar.es</a>/>
<br/>