[Bug target/81801] [PATCH] Difference of two pointers generates signed overflow

2021-12-28 Thread pinskia at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81801

Andrew Pinski  changed:

   What|Removed |Added

 Resolution|--- |DUPLICATE
 Status|UNCONFIRMED |RESOLVED

--- Comment #5 from Andrew Pinski  ---
Dup of bug 13421.

*** This bug has been marked as a duplicate of bug 13421 ***

[Bug target/81801] [PATCH] Difference of two pointers generates signed overflow

2017-08-11 Thread joseph at codesourcery dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81801

--- Comment #4 from joseph at codesourcery dot com  ---
On Fri, 11 Aug 2017, oss at malat dot biz wrote:

> One could solve it by dividing both pointers by the size before the
> subtraction, but that would make the operation more expensive.

See also what I said in bug 67999 comment 24.

The combination (subtract to produce a ptrdiff_t result, with modulo 
arithmetic on overflow, then divide in ptrdiff_t) isn't correct for 
objects too large in bytes for ptrdiff_t.  But the following should be 
correct: right shift (logical) both pointers for the power-of-2 factor in 
what you are dividing by, subtract (modulo), multiply (modulo) by the (mod 
2^n) reciprocal of the odd part of what you are dividing by, interpret the 
result as signed.

It's less efficient than code sequences that only work for objects less 
than half the address space, and such large objects can never work if you 
do pointer subtraction of pointers to char that are too far apart to be 
represented in ptrdiff_t.  I think it makes most sense to disallow such 
large objects properly (including in malloc and mmap), but an option to 
support pointer subtraction in them would not be ridiculous.

[Bug target/81801] [PATCH] Difference of two pointers generates signed overflow

2017-08-11 Thread oss at malat dot biz
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81801

--- Comment #3 from Petr Malat  ---
After reading the related part of the standard (actually, N1570 draft), I'm not
so sure about this. The semantics section in 6.5.6 says pointers have to be
from the same object and also the result must fit into the ptrdiff_t, which
range is [PTRDIFF_MIN, PTRDIFF_MAX], which has to be equal or larger than
[-65535, 65535].

So, theoretically it would be fine to use a shorter type for that, however
there is still a problem if the calculation is done as it is now for larger
objects as the difference is computed first at bytes and divided later by the
object size, so the overflow can still happen even the result fits in
[PTRDIFF_MIN, PTRDIFF_MAX].

One could solve it by dividing both pointers by the size before the
subtraction, but that would make the operation more expensive.

[Bug target/81801] [PATCH] Difference of two pointers generates signed overflow

2017-08-11 Thread pinskia at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81801

--- Comment #2 from Andrew Pinski  ---
Related to PR 80998.

[Bug target/81801] [PATCH] Difference of two pointers generates signed overflow

2017-08-11 Thread pinskia at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81801

Andrew Pinski  changed:

   What|Removed |Added

 Target||32bit target
  Component|c   |target

--- Comment #1 from Andrew Pinski  ---
Actually it is worse than you think.  The problem is __PTRDIFF_TYPE__ is
defined incorrectly if pointers can span across the sign bit (32bit).  There is
whole thread about this on gcc@.  The C/C++ language defines ptrdiff_t as a
type which can be used two take a difference of any two valid pointers and get
a signed difference.

In the case here 0x8002000f-0x0001000f should actually return a signed integer
that represents the space between those two pointers.