On Thu, Sep 14, 2023 at 1:50 PM Qing Zhao via Gcc-patches <gcc-patches@gcc.gnu.org> wrote: > > > > > On Sep 14, 2023, at 12:18 PM, Xi Ruoyao <xry...@xry111.site> wrote: > > > > On Thu, 2023-09-14 at 15:57 +0000, Qing Zhao via Gcc-patches wrote: > >> Currently, GCC behaves as following: > >> > >> /* True if overflow wraps around for the given integral or pointer type. > >> That > >> is, TYPE_MAX + 1 == TYPE_MIN. */ > >> #define TYPE_OVERFLOW_WRAPS(TYPE) \ > >> (POINTER_TYPE_P (TYPE) \ > >> ? flag_wrapv_pointer \ > >> : (ANY_INTEGRAL_TYPE_CHECK(TYPE)->base.u.bits.unsigned_flag \ > >> || flag_wrapv)) > >> > >> /* True if overflow is undefined for the given integral or pointer type. > >> We may optimize on the assumption that values in the type never > >> overflow. > >> > >> IMPORTANT NOTE: Any optimization based on TYPE_OVERFLOW_UNDEFINED > >> must issue a warning based on warn_strict_overflow. In some cases > >> it will be appropriate to issue the warning immediately, and in > >> other cases it will be appropriate to simply set a flag and let the > >> caller decide whether a warning is appropriate or not. */ > >> #define TYPE_OVERFLOW_UNDEFINED(TYPE) \ > >> (POINTER_TYPE_P (TYPE) \ > >> ? !flag_wrapv_pointer \ > >> : (!ANY_INTEGRAL_TYPE_CHECK(TYPE)->base.u.bits.unsigned_flag \ > >> && !flag_wrapv && !flag_trapv)) > >> > >> The logic above seems treating the pointer default as signed integer, > >> right? > > > > It only says the pointers cannot overflow, not the pointers are signed. > > > > printf("%d\n", (char *)(intptr_t)-1 > (char *)(intptr_t)1); > > > > produces 1 instead of 0. Technically this is invoking undefined > > behavior and a conforming implementation can output anything. But > > consider a 32-bit bare metal target where the linker can locate a "char > > x[512]" at [0x7fffff00, 0x80000100). The standard then requires &x[512] > >> &x[0], but if we do a signed comparison here we'll end up "&x[512] < > > &x[0]", this is non-conforming. > > So, are both the above examples showing that pointer based comparisons are > similar as unsigned integer comparison? -:) > Do we have examples on treating the pointer arithmetic as signed integer > arithmetic? (Really curious on this….) > > But anyway, if we cannot treat pointer type consistently as signed or > unsigned, shall we still need to catch pointer overflow? > > Currently, In GCC, we have -fsanitize=signed-integer-overflow to catch signed > integer overflow. > But we don’t have options to catch unsigned integer overflow and pointer > overflow. > > Shall we add two more options to catch unsigned integer overflow and pointer > overflow, like: > > -fsanitize=unsigned-integer-overflow > -fsanitize=pointer-overflow > > CLANG already provided -fsanitize=unsigned-integer-overflow. GCC might need > to do the same.
NO. There is no such thing as unsigned integer overflow. That option is badly designed and the GCC community has rejected a few times now having that sanitizer before. It is bad form to have a sanitizer for well defined code. Now -fsanitize=pointer-overflow is already there for GCC which was added in r8-2238-gc9b39a4955f56fe609ef5478 . LLVM/clang also provides it in the same timeframe too . https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80998 Thanks, Andrew > > And both Clang and GCC might also need to add -fsanitize=pointer-overflow? > > > IIUC, pointers are not integers, at all. If we treat them as integers > > in the brain we'll end up invoking undefined behavior sooner or later. > > Thus the wrapping/overflowing behavior of pointer is controlled by a > > different option than integers. > > However, the wrapping/overflowing behavior of pointers is still based on the > corresponding integer(or unsigned integer) wrapping/overflowing, right? > Do we have special pointer wrapping/overflowing? > > Qing > > > > > -- > > Xi Ruoyao <xry...@xry111.site> > > School of Aerospace Science and Technology, Xidian University >