This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug c/51455] New: Possible uninitialized register use when array subscript is unsigned
- From: "frederik.deweerdt at gmail dot com" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: Wed, 07 Dec 2011 18:10:09 +0000
- Subject: [Bug c/51455] New: Possible uninitialized register use when array subscript is unsigned
- Auto-submitted: auto-generated
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=51455
Bug #: 51455
Summary: Possible uninitialized register use when array
subscript is unsigned
Classification: Unclassified
Product: gcc
Version: unknown
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: c
AssignedTo: unassigned@gcc.gnu.org
ReportedBy: frederik.deweerdt@gmail.com
This happens on 4.4, 4.5 and 4.6, with and without strict aliasing.
The following C code:
======================
#include <string.h>
#define SIZE 128
int main(void)
{
int buf[SIZE];
char offsets[SIZE];
int index = 13;
int ret;
int i;
for (i = 0; i < SIZE; i++) {
buf[i] = i;
offsets[i] = (char)i;
}
asm volatile ("mov $0xfafafafafafafafa, %%rax" : : : "rax");
asm volatile ("nop" : : : "memory");
//ret = buf[offsets[index]];
/* XXX: Unsigned subscript here */
ret = buf[((unsigned char *)offsets)[index]];
asm volatile ("nop" : : : "memory");
return ret;
}
======================
Generates the following asm for the array access:
0x0000000000400476 <+54>: movabs $0xfafafafafafafafa,%rax
0x0000000000400480 <+64>: nop
0x0000000000400481 <+65>: movzbl 0x20d(%rsp),%eax
0x0000000000400489 <+73>: mov (%rsp,%rax,4),%eax
0x000000000040048c <+76>: nop
Note how we init eax first and then use rax as an index.
On the other hand, if I remove the cast to 'unsigned char *' (commented in the
snippet above), I get:
0x0000000000400476 <+54>: movabs $0xfafafafafafafafa,%rax
0x0000000000400480 <+64>: nop
0x0000000000400481 <+65>: movsbq 0x20d(%rsp),%rax
0x000000000040048a <+74>: mov (%rsp,%rax,4),%eax
0x000000000040048d <+77>: nop
Which initalizes the full rax register, as I would expect.
The questions I have are:
- shouldn't the full rax register be set in the 'unsigned char *' version as
well?
- is there any warranty that movzbl will zero eax's upper 4 bytes in the
'unsigned char *' version? I can't get the program to crash on the systems I
tested, and I would have expected they would, as AMD's docs don't mention the
zeroing of the upper 4 bytes.
Thanks,
Frederik