> 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.

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

Reply via email to