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.