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. 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. -- Xi Ruoyao <xry...@xry111.site> School of Aerospace Science and Technology, Xidian University