This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug c/15540] New: Accessing arrays in packed structs
- From: "h_jessen at hotmail dot com" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: 19 May 2004 13:08:14 -0000
- Subject: [Bug c/15540] New: Accessing arrays in packed structs
- Reply-to: gcc-bugzilla at gcc dot gnu dot org
Target description
------------------
Tested (and fails) on gcc 3.2.2 and 3.3.2 built for arm-elf cross compile.
Bug description
---------------
Accessing an array of packed structs is incorrect in some situations. See the
Test program example below.
Because of the 'packed' attributes, some of the 'i0' structure members will be
located on odd addresses (despite being a 32 bit value).
To avoid alignment faults it is important that these 'unaligned' integers are
read a bytes and concatenated using 'or' instructions.
gcc normally does this, but NOT in the example shown, which emits a simple 'load
32 bit register from memory' (ldr r3, [r3, #0]) instruction - THIS IS INCORRECT.
The choise of load stategy seems to be determined by the offset of Sa[0].i0
without taking into consideration that we read Sa[x].i0.
By changing the size of Ca (and thus moving the offset of Sa[0]) the emitted may
be altered (and even correct in some cases).
See attached assembler examples below for more details.
Compiler details:
-----------------
arm-elf-gcc -v
Reading specs from /usr/local/compilers/arm-elf/v2/lib/gcc-lib/arm-elf/3.2.
2/specs
Configured with: ../gcc-3.2.2/configure --target=arm-elf
--prefix=/usr/local/compilers/arm-elf/v2 --with-newlib --enable-languages=c
,c++ --with-gnu-ld --with-gnu-as --disable-shared --disable-symvers
--disable-nls --disable-threads
Thread model: single
gcc version 3.2.2
Command line
------------
arm-elf-gcc -save-temps -c test.c
Test program (preprocessor output)
----------------------------------
# 1 "test.c"
# 1 "<built-in>"
# 1 "<command line>"
# 1 "test.c"
typedef struct
{
char ch1;
int i0;
} __attribute__((packed)) Struct1;
typedef struct
{
char Ca[3];
Struct1 Sa[3];
} __attribute__((packed)) Struct2;
int function(int x)
{
Struct2 St =
{
{1,2,3},
{
{0,0},
{1,1},
{2,2}
}
};
int i = St.Sa[x].i0;
return i;
}
Assembler examples
------------------
INCORRECT CODE (size of Ca = 3)
ldr r3, [r3, #0] ; load r3 - won't work for index <> 0
:
mov r0, r3
CORRECT CODE (size of Ca = 2)
; load and esthablish r3 byte by byte - works for all indices
ldrb r1, [r2, #3] @ zero_extendqisi2
ldrb r3, [r2, #4] @ zero_extendqisi2
mov r3, r3, asl #8
orr r1, r3, r1
ldrb r3, [r2, #5] @ zero_extendqisi2
mov r3, r3, asl #16
orr r1, r3, r1
ldrb r3, [r2, #6] @ zero_extendqisi2
mov r3, r3, asl #24
orr r3, r3, r1
:
mov r0, r3
--
Summary: Accessing arrays in packed structs
Product: gcc
Version: 3.2.2
Status: UNCONFIRMED
Severity: normal
Priority: P2
Component: c
AssignedTo: unassigned at gcc dot gnu dot org
ReportedBy: h_jessen at hotmail dot com
CC: gcc-bugs at gcc dot gnu dot org
GCC build triplet: i686-pc-linux-gnu
GCC host triplet: i686-pc-linux-gnu
GCC target triplet: arm-elf
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=15540