On 22.10.20 21:24, Al Viro wrote: > On Thu, Oct 22, 2020 at 12:04:52PM -0700, Nick Desaulniers wrote: > >> Passing an `unsigned long` as an `unsigned int` does no such >> narrowing: https://godbolt.org/z/TvfMxe (same vice-versa, just tail >> calls, no masking instructions). >> So if rw_copy_check_uvector() is inlined into import_iovec() (looking >> at the mainline@1028ae406999), then children calls of >> `rw_copy_check_uvector()` will be interpreting the `nr_segs` register >> unmodified, ie. garbage in the upper 32b. > > FWIW, > > void f(unsinged long v) > { > if (v != 1) > printf("failed\n"); > } > > void g(unsigned int v) > { > f(v); > } > > void h(unsigned long v) > { > g(v); > } > > main() > { > h(0x100000001); > } > > must not produce any output on a host with 32bit int and 64bit long, regardless of > the inlining, having functions live in different compilation units, etc. > > Depending upon the calling conventions, compiler might do truncation in caller or > in a callee, but it must be done _somewhere_. The interesting case is having g() in a separate compilation unit and force-calling g() with 0x100000001 via inline ASM. So forcing garbage into high bits. I'll paly with it. -- Thanks, David / dhildenb