https://gcc.gnu.org/bugzilla/show_bug.cgi?id=64516
Bug ID: 64516 Summary: arm: wrong unaligned load generated Product: gcc Version: 4.9.2 Status: UNCONFIRMED Severity: normal Priority: P3 Component: target Assignee: unassigned at gcc dot gnu.org Reporter: markus at oberhumer dot com Created attachment 34391 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=34391&action=edit unaligned_load_bug.c to reproduce the problem. arm: bad code generated => run time crash - gcc 4.9.2 seems to forget the attribute(packed) in some cases. - please see the disassembly for get16_unaligned(). - put16_unaligned() is correct ! - FWIW, gcc 4.3.5 and clang 3.5 work ~Markus $ cat unaligned_load_bug.c typedef struct { char a[2]; } __attribute__((__packed__)) TU2; // OK: correct (but poor) code generated for the store void put16_unaligned(void *p, unsigned short v) { if (sizeof(TU2) == sizeof(v) && __alignof__(TU2) == 1) { *(TU2 *)p = *(const TU2 *)(const void *)(&v); } } // BUG: incorrect transformation into an aligned load => run time crash !! unsigned short get16_unaligned(const void *p) { unsigned short v; if (sizeof(TU2) == sizeof(v) && __alignof__(TU2) == 1) { *(TU2 *)(void *)(&v) = *(const TU2 *)p; } return v; } // aligned versions - just for comparison void put16_aligned(void *p, unsigned short v) { *(unsigned short *)p = *(&v); } unsigned short get16_aligned(const void *p) { unsigned short v; *(&v) = *(const unsigned short *)p; return v; } // EOF $ arm-linux-gnueabi-gcc-4.9 -v gcc version 4.9.2 (Ubuntu/Linaro 4.9.2-7ubuntu3) $ arm-linux-gnueabi-gcc-4.9 -march=armv4 -marm -O2 -Wall -W -Wcast-align -c unaligned_load_bug.c $ arm-linux-gnueabi-objdump -d unaligned_load_bug.o unaligned_load_bug.o: file format elf32-littlearm Disassembly of section .text: 00000000 <put16_unaligned>: 0: e52de004 push {lr} ; (str lr, [sp, #-4]!) 4: e24dd00c sub sp, sp, #12 8: e28d3008 add r3, sp, #8 c: e16310b2 strh r1, [r3, #-2]! 10: e3a02002 mov r2, #2 14: e1a01003 mov r1, r3 18: ebfffffe bl 0 <memcpy> 1c: e28dd00c add sp, sp, #12 20: e49de004 pop {lr} ; (ldr lr, [sp], #4) 24: e12fff1e bx lr 00000028 <get16_unaligned>: 28: e1d000b0 ldrh r0, [r0] 2c: e12fff1e bx lr 00000030 <put16_aligned>: 30: e1c010b0 strh r1, [r0] 34: e12fff1e bx lr 00000038 <get16_aligned>: 38: e1d000b0 ldrh r0, [r0] 3c: e12fff1e bx lr