public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug c/45779] New: pointer difference error/ptrdiff_t representability
@ 2010-09-24 16:06 aklauer at rumms dot uni-mannheim.de
  2010-09-27 18:27 ` [Bug c/45779] " aklauer at rumms dot uni-mannheim.de
  2015-02-20  8:29 ` pinskia at gcc dot gnu.org
  0 siblings, 2 replies; 3+ messages in thread
From: aklauer at rumms dot uni-mannheim.de @ 2010-09-24 16:06 UTC (permalink / raw)
  To: gcc-bugs

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=45779

           Summary: pointer difference error/ptrdiff_t representability
           Product: gcc
           Version: 4.6.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c
        AssignedTo: unassigned@gcc.gnu.org
        ReportedBy: aklauer@rumms.uni-mannheim.de


Note: initially found on gcc 4.3.2, confirmed on 4.6.0 20100924 from svn.

Consider the following program:
<code>
/* test.c */
#include<assert.h>
#include<inttypes.h>
#include<stddef.h>
#include<stdio.h>
#include<stdlib.h>

int main(int argc, char ** argv) {
        printf("ptrdiff_t max: %ju, size_t max: %ju\n", (uintmax_t)
PTRDIFF_MAX, (uintmax_t) SIZE_MAX);
        assert (argc > 1);
        size_t size = atoll(argv[1]);
        printf("requested array size: %zu\n", size);
        assert (size > 0);
        uint16_t * array = malloc(size * sizeof(*array));
        assert (array != NULL);
        printf("array one-past-end/start difference: %td\n",
                        &array[size] - &array[0]);
}
</code>

$ gcc -std=c99 -pedantic -Wall -Wextra test.c
$ ./a.out 1200000000
ptrdiff_t max: 2147483647, size_t max: 4294967295
requested array size: 1200000000
array one-past-end/start difference: -947483648

The output "-947483648" violates the C99 standard, it should be "1200000000".

This program was compiled and run on an IA-32 host with 2.5 GiB memory.

The pointer returned by the successful call to malloc() points to an array of
1200000000 uint16_t's. In the present case, the number 1200000000 is smaller
than PTRDIFF_MAX and thus representable by the ptrdiff_t type. Hence, by the
C99 standard, 6.5.6p9, the expression &array[size] - &array[0] above is defined
to have type ptrdiff_t and value 1200000000.

Note that if one replaced uint16_t with char in the above code and called the
program with argument 2400000000 (a number larger than PTRDIFF_MAX), the
behaviour would be undefined. Therefore I suspect that, internally, gcc first
calculates the value of &array[size] - &array[0] as if array had type
pointer-to-char and then erroneously interprets the result as a negative 32-bit
2's complement signed integer, which it then divides by 2 (that is,
sizeof(uint16_t)) with a signed integer division.

Best regards,
Alexander

-- 
Configure bugmail: http://gcc.gnu.org/bugzilla/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are on the CC list for the bug.


^ permalink raw reply	[flat|nested] 3+ messages in thread

* [Bug c/45779] pointer difference error/ptrdiff_t representability
  2010-09-24 16:06 [Bug c/45779] New: pointer difference error/ptrdiff_t representability aklauer at rumms dot uni-mannheim.de
@ 2010-09-27 18:27 ` aklauer at rumms dot uni-mannheim.de
  2015-02-20  8:29 ` pinskia at gcc dot gnu.org
  1 sibling, 0 replies; 3+ messages in thread
From: aklauer at rumms dot uni-mannheim.de @ 2010-09-27 18:27 UTC (permalink / raw)
  To: gcc-bugs

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=45779

--- Comment #1 from Alexander <aklauer at rumms dot uni-mannheim.de> 2010-09-27 16:20:48 UTC ---
While fiddling around a bit more I found that gcc normally doesn't let me
create objects whose size exceeds PTRDIFF_MAX. For objects of size at most
PTRDIFF_MAX, the bug cannot be triggered. The only function I found which does
create such large objects is malloc(). Presumably, its companions calloc() and
realloc() do so as well.

In this light, the best fix for this bug seems to be for malloc() and
companions to simply return NULL upon a request for an object whose size
exceeds PTRDIFF_MAX.


^ permalink raw reply	[flat|nested] 3+ messages in thread

* [Bug c/45779] pointer difference error/ptrdiff_t representability
  2010-09-24 16:06 [Bug c/45779] New: pointer difference error/ptrdiff_t representability aklauer at rumms dot uni-mannheim.de
  2010-09-27 18:27 ` [Bug c/45779] " aklauer at rumms dot uni-mannheim.de
@ 2015-02-20  8:29 ` pinskia at gcc dot gnu.org
  1 sibling, 0 replies; 3+ messages in thread
From: pinskia at gcc dot gnu.org @ 2015-02-20  8:29 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=45779

Andrew Pinski <pinskia at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|UNCONFIRMED                 |RESOLVED
         Resolution|---                         |INVALID

--- Comment #2 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
https://gcc.gnu.org/ml/gcc/2011-08/msg00221.html


^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2015-02-20  8:29 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-09-24 16:06 [Bug c/45779] New: pointer difference error/ptrdiff_t representability aklauer at rumms dot uni-mannheim.de
2010-09-27 18:27 ` [Bug c/45779] " aklauer at rumms dot uni-mannheim.de
2015-02-20  8:29 ` pinskia at gcc dot gnu.org

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).