https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99578

--- Comment #29 from Goswin von Brederlow <goswin-v-b at web dot de> ---
(In reply to Jakub Jelinek from comment #26)

> That is nonsense.  The amount of code in the wild that relies on (type
> *)CONSTANT
> working is insane, you can't annotate it all.  And it has worked fine for
> decades.  The pointers aren't invalid, they point to valid objects in the
> address space.
> POSIX supports MAP_FIXED for a reason (and in many embedded cases one
> doesn't even have an MMU and I/O or other special areas are mapped directly).

A cast from integer to pointer is implementation defined behavior except for

1) 0 which must cast to NULL / nullptr
2) if the integer value was constructed by casting a pointer to integer of
suitable size

There is no garantee in the C standard that '(type *)CONSTANT' will actually
point to the hardware address 'CONSTANT'. It's just how gcc happens to do it in
most cases. So no, your code is not fine. It is fragile. It relies on
implementation details of gcc. But lets not argue about that.


Detecting NULL pointer access and offsets to it is a good thing, except where
it isn't. It's unfortunate it also catches other stuff. Under AmigaOS the
pointer to the exec.library (no program can work without that) is stored in
address 4. So there isn't an universal value of "this is big enough not to be
an offset to NULL".

Detecting if an expression involves NULL might be hard. If it starts as
NULL->member then it's easy. What about (&x - &x)+offsetof(X.member) or
(uintptr_t)&x.member - (uintptr_t)&x or similar stuff you easily get with
macros. On the other side (T*)0x45634534 should be easy to detect as not being
NULL+offset. It's a literal. But the grey zone inbetween the easy cases might
be to big to be useful.

Alternatively an annotation for this would actually go nicely with another bug
I reported: 'add feature to create a pointer to a fixed address as constexpr'
[1].  The annotation would avoid the warning and also make it a pointer literal
that can be used in constexpr (appart from accessing the address). It could
also cause gcc to handle the case where CONSTANT can't just be cast to pointer
and work. Like when using address authentication on ARMv8 CPUs, to name
something modern.

And the size of the object the pointer points to can be taken from its type,
i.e. the pointer is to a single object and never an (infinite) array. If you
want a pointer to an array then cast it to an array of the right size.

--
[1] https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104514

Reply via email to