[PATCH 06/11] Sptr: avoided potentially undefined behaviour.

Max Romanov max.romanov at gmail.com
Sat Jun 18 09:39:57 UTC 2022


> But the pointer itself does constitute another separate object.  And
that object is the one that is stored in the union (the uint8_t data is
not stored in the union, but in some other allocated memory (probably)).

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.

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.

--
Max

-----Original Message-----
From: Alejandro Colomar <alx.manpages at gmail.com>
To: Max Romanov <max.romanov at gmail.com>, Andrew Clayton <andrew at digital-domain.net>
Cc: unit at nginx.org
Sent: сб, 18 июн. 2022 2:15
Subject: Re: [PATCH 06/11] Sptr: avoided potentially undefined behaviour.

Hi Max

On 6/18/22 01:04, Max Romanov wrote:
> I'm sorry to be a pain,

No problem :)

  but the key thing is: ".. read from another
> object..".

In this case, ISO C uses the term object to refer to a broader concept, 
that includes any variable.

3.15/1,2:
"
object
region of data storage in the execution environment, the contents of 
which can represent values
"

> In the statement you are trying to "fix", the "base" does not 
> actually _read_ from the object (structure, to be precise), instead the 
> address of the structure itself used. In other words, "p->base" is a 
> shortcut for "(uint8_t *) p".

the region of data storage pointed to by `p->base` would be an object 
(of type uint8_t, or maybe uint8_t[]).

But the pointer itself does constitute another separate object.  And 
that object is the one that is stored in the union (the uint8_t data is 
not stored in the union, but in some other allocated memory (probably)).

Since we are reading a member of the union (and each member is an 
object, by definition, even if it's a pointer), and storing the value 
into another member of the union, that's not valid.

As pointed by @supercat in StackOverflow (in the link I provided), the 
rationale was probably to allow compilers to do some optimizations, or 
for example, copy byte by byte; in archs where the union members are 
larger than a register, this will definitely cause a bug; in archs where 
the union members fit into a register (as in our case), the code is 
likely to work, but the standard makes no guarantees about it, and a 
compiler may still do bad stuff.  It's better to be safe.

Cheers,

Alex
>> <https://stackoverflow.com/a/72652427/6872717 
-- 
Alejandro Colomar
<http://www.alejandro-colomar.es/>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mailman.nginx.org/pipermail/unit/attachments/20220618/45ab0719/attachment.htm>


More information about the unit mailing list