diff --git a/gcc/ChangeLog b/gcc/ChangeLog index a1b0097cb8d..1ab1c66f7ad 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2005-11-03 Andrew Pinski + + PR middle-end/23155 + * gimplifier.c (gimplify_expr): Create a temporary for lvalue + CONSTRUCTOR. + 2005-11-03 Daniel Berlin Fix PR tree-optimization/24351 diff --git a/gcc/gimplify.c b/gcc/gimplify.c index 52e70bdad5e..9e25aef25c2 100644 --- a/gcc/gimplify.c +++ b/gcc/gimplify.c @@ -4323,6 +4323,15 @@ gimplify_expr (tree *expr_p, tree *pre_p, tree *post_p, *expr_p = temp; ret = GS_OK; } + /* C99 code may assign to an array in a constructed + structure or union, and this has undefined behavior only + on execution, so create a temporary if an lvalue is + required. */ + else if (fallback == fb_lvalue) + { + *expr_p = get_initialized_tmp_var (*expr_p, pre_p, post_p); + lang_hooks.mark_addressable (*expr_p); + } else ret = GS_ALL_DONE; break; diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index ffb3ee09409..9678651670f 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,11 @@ +2005-11-03 Andrew Pinski + + PR middle-end/23155 + * g++.dg/ext/c99struct1.C: New test. + * gcc.dg/union-cast-1.c: New test. + * gcc.dg/union-cast-2.c: New test. + * gcc.dg/union-cast-3.c: New test. + 2005-11-03 Andrew Pinski PR middle-end/24589 diff --git a/gcc/testsuite/g++.dg/ext/c99struct1.C b/gcc/testsuite/g++.dg/ext/c99struct1.C new file mode 100644 index 00000000000..93e84b46039 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/c99struct1.C @@ -0,0 +1,12 @@ +// { dg-options "" } +// C99 anon struct variable with array accesses. + +struct s { int a[1]; }; + +void +foo5 (void) +{ + ((struct s) { { 0 } }).a[0] = 1; +} + + diff --git a/gcc/testsuite/gcc.dg/union-cast-1.c b/gcc/testsuite/gcc.dg/union-cast-1.c new file mode 100644 index 00000000000..1d7f4d549d8 --- /dev/null +++ b/gcc/testsuite/gcc.dg/union-cast-1.c @@ -0,0 +1,14 @@ +/* { dg-do compile } */ +/* { dg-options "-std=gnu89" } */ +/* A combine of two extensions to C89 are used here. + First casts to unions is used. + Second subscripting non lvalue arrays, this is in C99. */ + +union vx {short f[8]; int v;}; +int vec; + +void +foo5 (int vec) +{ + ((union vx) vec).f[5] = 1; +} diff --git a/gcc/testsuite/gcc.dg/union-cast-2.c b/gcc/testsuite/gcc.dg/union-cast-2.c new file mode 100644 index 00000000000..9aac5caa291 --- /dev/null +++ b/gcc/testsuite/gcc.dg/union-cast-2.c @@ -0,0 +1,15 @@ +/* { dg-do compile } */ +/* { dg-options "-std=c89 -pedantic-errors" } */ +/* PR 23155 + We should get two error messages, one about union cast + and the other about array access for non lvalues. */ + + +union vx {short f[8]; int v;}; +int vec; + +void +foo5 (int vec) +{ + ((union vx) vec).f[5] = 1; /* { dg-error "(forbids subscripting)|(forbids casts to union type)" } */ +} diff --git a/gcc/testsuite/gcc.dg/union-cast-3.c b/gcc/testsuite/gcc.dg/union-cast-3.c new file mode 100644 index 00000000000..5f9b9f86870 --- /dev/null +++ b/gcc/testsuite/gcc.dg/union-cast-3.c @@ -0,0 +1,14 @@ +/* { dg-do compile } */ +/* { dg-options "-std=c99 -pedantic-errors" } */ +/* PR 23155 + We should get one error messag, one about union cast. */ + + +union vx {short f[8]; int v;}; +int vec; + +void +foo5 (int vec) +{ + ((union vx) vec).f[5] = 1; /* { dg-error "forbids casts to union type" } */ +}