On Thu, Nov 5, 2020 at 1:14 PM Alexander Monakov <amona...@ispras.ru> wrote:

> > I was also thinking of introducing of operand modifier, but Richi
> > advises the following:
> >
> > --cut here--
> > typedef __UINTPTR_TYPE__ uintptr_t;
> >
> > __seg_fs int x;
> >
> > uintptr_t test (void)
> > {
> >  uintptr_t *p = (uintptr_t *)(uintptr_t) &x;
> >  uintptr_t addr;
> >
> >  asm volatile ("lea %1, %0" : "=r"(addr) : "m"(*p));
> >
> >  return addr;
> > }
>
> This is even worse undefined behavior compared to my solution above:
> this code references memory in uintptr_t type, while mine preserves the
> original type via __typeof. So this can visibly break with TBAA (though
> the kernel uses -fno-strict-aliasing, so this particular concern wouldn't
> apply there).

Agreed, but I was trying to solve this lone use case in the kernel. It
fits this particular usage, so I found a bit of overkill to implement
the otherwise useless operand modifier in gcc. As discussed
previously, these hacks are needed exclusively in asm templates, they
are not needed in "normal" C code.
>
> If you don't care about preserving sizeof and type you can use a cast to char:
>
> #define strip_as(mem) (*(char *)(intptr_t)&(mem))

I hope that a developer from kernel can chime in and express their
opinion on the proposed approaches.

Uros.

Reply via email to