This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug c/15540] New: Accessing arrays in packed structs


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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]