Skip to content
  • Alex Richardson's avatar
    Use uintptr_t, if avail, for pointer-to-int casts · a72816ed
    Alex Richardson authored
    Although sizeof(void *) == sizeof(size_t) for all architectures that are
    currently supported by libjpeg-turbo, such is not guaranteed by the C
    standard.  Specifically, CHERI-enabled architectures (e.g. CHERI-RISC-V
    or Arm's Morello) use capability pointers that are twice the size of
    size_t (128 bits for Morello and RV64), so casting to size_t strips the
    upper bits of the pointer (including the validity bit) and makes it
    non-deferenceable, as indicated by the following compiler warning:
    
      warning: cast from provenance-free integer type to pointer type will
      give pointer that can not be dereferenced
      [-Werror,-Wcheri-capability-misuse]
        cvalue = values = (JCOEF *)PAD((size_t)values_unaligned, 16);
    
    Ignoring this warning results in a run-time crash.  Casting pointers to
    uintptr_t, if it is available, avoids this problem, since uintptr_t is
    defined as an unsigned integer type that can hold a pointer value.
    
    Since C89 compatibility is still necessary in libjpeg-turbo, this commit
    introduces a new typedef for pointer-to-integer casts that uses a
    GNU-specific extension available in GCC 4.6+ and Clang 3.0+ and falls
    back to using size_t if the extension is unavailable.  The only other
    options would require C99 or Clang-specific builtins.
    
    Closes #538
    a72816ed
To find the state of this project's repository at the time of any of these versions, check out the tags.