This is the mail archive of the 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]

[PATCH] Avoid unaligned memory reference on ARM

I propose the following patch for gcc-3.3. Currently gcc-3.3 may
loose track of (mis)alignment of paramenters. In effect on arm-linux
misaligned memory references are generated. The program below
ilustrates the problem. Compiled as:
gcc -Wall -fpack-struct insan4.c

Odd array elements are printed garbled. The affects GNU Pascal,
(it showed as failure of `insan.pas' test). Since classic pascal
uses packed arrays of chars as strings (and short strings are
frequently passed by value) practical impact is quite serious.

The patch below is actually identical to change in 3.4 which
seem to correspond to change log entry:

Fri Apr  4 17:43:52 2003  Olivier Hainque <>

        * emit-rtl.c (get_mem_attrs): Adjust alignment tests determining
	  use of default attributes to agree MEM_ALIGN macro.

I developed equivalent patch for GNU Pascal, and during testing I found
out that 3.4 code is already changed. I found no trace of such patch on
gcc-patches so I do not why 3.3 was not changed (lack of testcase ???).
I bootstraped 3.3.2 with the patch and found no new regressions.
However, the patch changes code only on STRICT_ALIGNMENT platforms,
and ATM I am unable to run full bootstrap on such platform (I did check
that patch causes no regression for GPC on arm-linux and sparc-solaric2.6). 

The testcase:
-------------------<cut here>---------------
#include <stdio.h>

typedef struct {char c[10];} alfa __attribute__ ((packed));
alfa datas[6] = {
        {"red       "},
        {"blue      "},
        {"white     "},
        {"white     "},
        {"green     "},
        {"green     "}

void printword(alfa alf)
        int i;
        for (i=0; i<10; i++) putchar(alf.c[i]);

int main(void)
        int i;
        for(i=0; i<6; i++) printword(datas[i]);
        return 0;
---------------------------<cut here>-----------------------

The patch:

diff -ru gcc-3.3.2.orig/gcc/emit-rtl.c gcc-3.3.2/gcc/emit-rtl.c
--- gcc-3.3.2.orig/gcc/emit-rtl.c	Wed Jul  9 02:30:20 2003
+++ gcc-3.3.2/gcc/emit-rtl.c	Sat Nov 15 19:03:38 2003
@@ -296,13 +296,14 @@
   mem_attrs attrs;
   void **slot;
-  /* If everything is the default, we can just return zero.  */
+  /* If everything is the default, we can just return zero.
+     This must match what the corresponding MEM_* macros return when the
+     field is not present.  */
   if (alias == 0 && expr == 0 && offset == 0
       && (size == 0
 	  || (mode != BLKmode && GET_MODE_SIZE (mode) == INTVAL (size)))
-      && (align == BITS_PER_UNIT
-	      && mode != BLKmode && align == GET_MODE_ALIGNMENT (mode))))
+      && (STRICT_ALIGNMENT && mode != BLKmode
+	  ? align == GET_MODE_ALIGNMENT (mode) : align == BITS_PER_UNIT))
     return 0;
   attrs.alias = alias;

                              Waldek Hebisch 

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