https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69051

            Bug ID: 69051
           Summary: Misaligned read from the stack when using odd sized
                    character array
           Product: gcc
           Version: 5.3.1
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: target
          Assignee: unassigned at gcc dot gnu.org
          Reporter: m.frohiky at gmail dot com
  Target Milestone: ---

This simple code:

void filler(unsigned char *blk);
long f(void) {
        unsigned char blk[65];
        filler(blk);
        return
                ((unsigned long)blk[0] << 24) |
                ((unsigned long)blk[1] << 16) |
                ((unsigned long)blk[2] <<  8) |
                ((unsigned long)blk[3] <<  0);
}

compiled with any kind of optimization:

m68k-linux-gnu-gcc -S p.c -O2

generates assembly code that can not be executed due to the misaligned read
from the stack:

f2:
        link.w %fp,#-68
        pea -65(%fp)
        jsr filler
        move.l -65(%fp),%d0    # this line fails
        unlk %fp
        rts

move.l fails because -65(%fp) is an odd address.

One possible workaround is to mark used elements as modified by inline
assembly:
        addr  = ((unsigned long)blk[0] << 24);
        asm("" : "=m"(blk[0]));
        addr |= ((unsigned long)blk[1] << 16);
        asm("" : "=m"(blk[1]));
        addr |= ((unsigned long)blk[2] <<  8);
        asm("" : "=m"(blk[2]));
        addr |= ((unsigned long)blk[3] <<  0);


The compiler is installed from Debian repository.

Reply via email to