Question on -fwrapv and -fwrapv-pointer

Xi Ruoyao xry111@xry111.site
Thu Sep 14 16:18:18 GMT 2023


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


More information about the Gcc-patches mailing list