This is the mail archive of the gcc-patches@gcc.gnu.org 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 for bug 17855


This patch fixes bug 17855, an ICE on code which tries to modify
certain non-lvalue arrays (in structures in function returns or
conditional expressions); this code is valid as long as it is never
executed.  The fix (entirely outside the C front end) arranges for
temporary variables to be created (fixing the first ICE) and for those
variables to be marked addressable (fixing the second ICE which was
encountered with the first attempt at a fix discussed in that PR).

Bootstrapped with no regressions, mainline and 4.0 branch, on
x86_64-unknown-linux-gnu.  OK to commit?

-- 
Joseph S. Myers               http://www.srcf.ucam.org/~jsm28/gcc/
    jsm@polyomino.org.uk (personal mail)
    joseph@codesourcery.com (CodeSourcery mail)
    jsm28@gcc.gnu.org (Bugzilla assignments and CCs)

2005-03-30  Joseph S. Myers  <joseph@codesourcery.com>

	PR c/17855
	* gimplify.c (gimplify_expr): Create a temporary for lvalue
	COND_EXPR and CALL_EXPR.

testsuite:
2005-03-30  Joseph S. Myers  <joseph@codesourcery.com>

	PR c/17855
	* gcc.c-torture/compile/struct-non-lval-1.c,
	gcc.c-torture/compile/struct-non-lval-2.c,
	gcc.c-torture/compile/struct-non-lval-3.c: New tests.

diff -rupN GCC.orig/gcc/gimplify.c GCC/gcc/gimplify.c
--- GCC.orig/gcc/gimplify.c	2005-03-23 19:38:18.000000000 +0000
+++ GCC/gcc/gimplify.c	2005-03-30 17:41:41.000000000 +0000
@@ -3810,10 +3810,28 @@ gimplify_expr (tree *expr_p, tree *pre_p
 	case COND_EXPR:
 	  ret = gimplify_cond_expr (expr_p, pre_p, post_p, NULL_TREE,
 				    fallback);
+	  /* C99 code may assign to an array in a structure value of a
+	     conditional expression, and this has undefined behavior
+	     only on execution, so create a temporary if an lvalue is
+	     required.  */
+	  if (fallback == fb_lvalue)
+	    {
+	      *expr_p = get_initialized_tmp_var (*expr_p, pre_p, post_p);
+	      lang_hooks.mark_addressable (*expr_p);
+	    }
 	  break;
 
 	case CALL_EXPR:
 	  ret = gimplify_call_expr (expr_p, pre_p, fallback != fb_none);
+	  /* C99 code may assign to an array in a structure returned
+	     from a function, and this has undefined behavior only on
+	     execution, so create a temporary if an lvalue is
+	     required.  */
+	  if (fallback == fb_lvalue)
+	    {
+	      *expr_p = get_initialized_tmp_var (*expr_p, pre_p, post_p);
+	      lang_hooks.mark_addressable (*expr_p);
+	    }
 	  break;
 
 	case TREE_LIST:
diff -rupN GCC.orig/gcc/testsuite/gcc.c-torture/compile/struct-non-lval-1.c GCC/gcc/testsuite/gcc.c-torture/compile/struct-non-lval-1.c
--- GCC.orig/gcc/testsuite/gcc.c-torture/compile/struct-non-lval-1.c	1970-01-01 00:00:00.000000000 +0000
+++ GCC/gcc/testsuite/gcc.c-torture/compile/struct-non-lval-1.c	2005-03-30 16:51:05.000000000 +0000
@@ -0,0 +1,7 @@
+/* Bug c/17855.  */
+struct foo {char x, y, z[2];};
+struct foo f();
+void bar(int baz)
+{
+  f().z[baz] = 1;
+}
diff -rupN GCC.orig/gcc/testsuite/gcc.c-torture/compile/struct-non-lval-2.c GCC/gcc/testsuite/gcc.c-torture/compile/struct-non-lval-2.c
--- GCC.orig/gcc/testsuite/gcc.c-torture/compile/struct-non-lval-2.c	1970-01-01 00:00:00.000000000 +0000
+++ GCC/gcc/testsuite/gcc.c-torture/compile/struct-non-lval-2.c	2005-03-30 16:51:05.000000000 +0000
@@ -0,0 +1,7 @@
+/* Bug c/17855, using conditional expression for non-lvalue.  */
+struct foo {char x, y, z[2];};
+struct foo p, q; int r;
+void bar(int baz)
+{
+  (r ? p : q).z[baz] = 1;
+}
diff -rupN GCC.orig/gcc/testsuite/gcc.c-torture/compile/struct-non-lval-3.c GCC/gcc/testsuite/gcc.c-torture/compile/struct-non-lval-3.c
--- GCC.orig/gcc/testsuite/gcc.c-torture/compile/struct-non-lval-3.c	1970-01-01 00:00:00.000000000 +0000
+++ GCC/gcc/testsuite/gcc.c-torture/compile/struct-non-lval-3.c	2005-03-30 16:51:05.000000000 +0000
@@ -0,0 +1,7 @@
+/* Bug c/17855, using assignment for non-lvalue.  */
+struct foo {char x, y, z[2];};
+struct foo p, q;
+void bar(int baz)
+{
+  (p = q).z[baz] = 1;
+}


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