Hi Jeff, please find attached the patch (incl. test cases) for the unaligned read BUG that I found while investigating on PR#57748: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=57748
one test case is this one: pr57748-3.c: /* PR middle-end/57748 */ /* { dg-do run } */ /* wrong code in expand_expr_real_1. */ #include <stdlib.h> extern void abort (void); typedef long long V __attribute__ ((vector_size (2 * sizeof (long long)), may_alias)); typedef struct S { V a; V b[0]; } P __attribute__((aligned (1))); struct __attribute__((packed)) T { char c; P s; }; void __attribute__((noinline, noclone)) check (P *p) { if (p->b[0][0] != 3 || p->b[0][1] != 4) abort (); } void __attribute__((noinline, noclone)) foo (struct T *t) { V a = { 3, 4 }; t->s.b[0] = a; } int main () { struct T *t = (struct T *) calloc (128, 1); foo (t); check (&t->s); free (t); return 0; } and the other one is pr57748-4.c: /* PR middle-end/57748 */ /* { dg-do run } */ /* wrong code in expand_expr_real_1. */ #include <stdlib.h> extern void abort (void); typedef long long V __attribute__ ((vector_size (2 * sizeof (long long)), may_alias)); typedef struct S { V b[1]; } P __attribute__((aligned (1))); struct __attribute__((packed)) T { char c; P s; }; void __attribute__((noinline, noclone)) check (P *p) { if (p->b[1][0] != 3 || p->b[1][1] != 4) abort (); } void __attribute__((noinline, noclone)) foo (struct T *t) { V a = { 3, 4 }; t->s.b[1] = a; } int main () { struct T *t = (struct T *) calloc (128, 1); foo (t); check (&t->s); free (t); return 0; } The patch does add a boolean "expand_reference" parameter to expand_expr_real and expand_expr_real_1. I pass true when I intend to use the returned memory context as an array reference, instead of a value. At places where mis-aligned values are extracted, I do not return a register with the extracted mis-aligned value if expand_reference is true. When I have a VIEW_CONVERT_EXPR I pay attention to pass down the outer "expand_reference" to the inner expand_expr_real call. Expand_reference, is pretty much similar to the expand_modifier "EXPAND_MEMORY". Boot-strapped and regression-tested on X86_64-pc-linux-gnu (many times). Ok for trunk? Thanks Bernd.
2013-11-07 Bernd Edlinger <bernd.edlin...@hotmail.de> PR middle-end/57748 * expr.h (expand_expr_real, expand_expr_real_1): Add new parameter expand_reference. (expand_expr, expand_normal): Adjust. * expr.c (expand_expr_real, expand_expr_real_1): Add new parameter expand_reference. Use expand_reference to expand inner references. (store_expr): Adjust. * cfgexpand.c (expand_call_stmt): Adjust. testsuite: 2013-11-07 Bernd Edlinger <bernd.edlin...@hotmail.de> PR middle-end/57748 * gcc.dg/torture/pr57748-3.c: New test. * gcc.dg/torture/pr57748-4.c: New test.
patch-pr57748-2.diff
Description: Binary data