Article View: gnu.gcc.bug
Article #6066Re: Signed or unsigned address comparisons?
From: Linus Torvalds
Date: Fri, 13 Dec 1996 00:00
Date: Fri, 13 Dec 1996 00:00
74 lines
2954 bytes
2954 bytes
In article <58n6df$rgb@atlas.xylogics.com>,
James Carlson <carlson@xylogics.com> wrote:
>
>In article <c7574ef08b6629a6c3f2218773ac27bf@wretched.mailer.com>, "Richard Kiessig" <rick@kiessig.com> writes:
>|> GCC seems to generate address comparisons in RTL as signed compares (i.e.
>|> "GT" instead of "GTU"). Is there a reason for this? Shouldn't address
>|> compares be unsigned? It probably doesn't matter on most machines, but it
>|> does on the one I'm working on.
This is definitely a bug on almost all architectures.. It just doesn't
show up that often on most of them.
>According to section 6.3.9 of the ANSI standard, the only requirement
>on the relational operators when used with addresses is that they
>operate correctly within the same object. So as long as the compiler
>never allocates an object which spans the magic + to - boundary and
>malloc() never returns a block which spans that boundary, then signed
>and unsigned are equivalent, and any code which doesn't behave correctly
>with this definition isn't ANSI code.
Not just the compiler.. The OS can certainly make a difference, and
while ANSI may not mention stuff like "mmap()", a signed comparison can
certainly be a real problem.
On many 32-bit systems the user space will contain the +/- boundary (not
all, because in many cases the +/- boundary is also the kernel/user
boundary). On Linux/x86, for example, valid user accesses are from 0 to
0xbfffffff, and objects most certainly can span the +/- boundary.
Simple test program to follow. It prints out
Buggy compiler
If something is wrong, but it seems like this problem is fixed at least
in gcc-2.7.2..
Linus
-----
#include <stdio.h>
#include <sys/mman.h>
#include <sys/types.h>
/*
* This assumes 32-bit machines and a page-size that
* is <= 16384. Edit to suit..
*
* Run this program with stdin redirected from something
* that can be mmap'ed - generally not the tty ;)
*/
#define MEM 16384
#define START ((char *)(0x80000000-MEM))
#define LEN (2*MEM)
int main(int argc, char **argv)
{
char * p;
p = mmap(START, LEN, PROT_READ|PROT_WRITE,
MAP_FIXED|MAP_FILE|MAP_PRIVATE, 0, 0);
if (p == (caddr_t) -1) {
perror("mmap");
exit(1);
}
if (p > p+LEN) {
fprintf(stderr, "Buggy compiler\n");
exit(1);
}
printf("ok\n");
return 0;
}
Technical Details
Message-ID:
<58rsfj$9ft@linux.cs.Helsinki.FI>Path:
arc1-ca.pugleaf.net!unknown!not-for-mailReferences:
<c7574ef08b6629a6c3f2218773ac27bf@wretched.mailer.com>Show Full Headers
Complete Article Headers
X-Google-Language: ENGLISH,ASCII-7-bit X-Google-Thread: 113d02,76e11d8cd428fc2b X-Google-Attributes: gid113d02,public From: torvalds@linux.cs.Helsinki.FI (Linus Torvalds) Subject: Re: Signed or unsigned address comparisons? Date: 1996/12/13 Message-ID: <58rsfj$9ft@linux.cs.Helsinki.FI> X-Deja-AN: 203917725 sender: bug-gcc-request@prep.ai.mit.edu references: <c7574ef08b6629a6c3f2218773ac27bf@wretched.mailer.com> organization: University of Helsinki x-gateway: relay5.UU.NET from bug-gcc to gnu.gcc.bug; Fri, 13 Dec 1996 10:28:11 EST newsgroups: gnu.gcc.bug