From 936d04b695e69a1ea5a22bba68c8e37f086f5e96 Mon Sep 17 00:00:00 2001
From: Jan Hubicka <jh@suse.cz>
Date: Sat, 23 Jun 2007 13:58:18 +0200
Subject: [PATCH] re PR middle-end/31541 (cannot take address of bit field)

	PR middle-end/31541
	* gimplify.c (mark_addressable): New function.
	(gimplify_modify_expr_rhs, gimplify_addr_expr, gimplify_expr): Use it.

	* gcc.c-torture/compile/pr31541.c: New.

From-SVN: r125971
---
 gcc/ChangeLog                                 |  6 ++++
 gcc/gimplify.c                                | 28 +++++++++++++------
 gcc/testsuite/ChangeLog                       |  4 +++
 gcc/testsuite/gcc.c-torture/compile/pr31541.c |  9 ++++++
 4 files changed, 39 insertions(+), 8 deletions(-)
 create mode 100644 gcc/testsuite/gcc.c-torture/compile/pr31541.c

diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 09f25762d19d..204a37f69733 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@
+2007-06-23  Jan Hubicka  <jh@suse.cz>
+
+	PR middle-end/31541
+	* gimplify.c (mark_addressable): New function.
+	(gimplify_modify_expr_rhs, gimplify_addr_expr, gimplify_expr): Use it.
+
 2007-06-19  Uros Bizjak  <ubizjak@gmail.com>
 
 	PR middle-end/32374
diff --git a/gcc/gimplify.c b/gcc/gimplify.c
index c93bb4449d5b..e4d650b78ab4 100644
--- a/gcc/gimplify.c
+++ b/gcc/gimplify.c
@@ -117,6 +117,17 @@ static enum gimplify_status gimplify_compound_expr (tree *, tree *, bool);
 static bool cpt_same_type (tree a, tree b);
 #endif
 
+/* Mark X addressable.  Unlike the langhook we expect X to be in gimple
+   form and we don't do any syntax checking.  */
+static void
+mark_addressable (tree x)
+{
+  while (handled_component_p (x))
+    x = TREE_OPERAND (x, 0);
+  if (TREE_CODE (x) != VAR_DECL && TREE_CODE (x) != PARM_DECL)
+    return ;
+  TREE_ADDRESSABLE (x) = 1;
+}
 
 /* Return a hash value for a formal temporary table entry.  */
 
@@ -3434,7 +3445,7 @@ gimplify_modify_expr_rhs (tree *expr_p, tree *from_p, tree *to_p, tree *pre_p,
 	    if (use_target)
 	      {
 		CALL_EXPR_RETURN_SLOT_OPT (*from_p) = 1;
-		lang_hooks.mark_addressable (*to_p);
+		mark_addressable (*to_p);
 	      }
 	  }
 
@@ -3957,6 +3968,8 @@ gimplify_addr_expr (tree *expr_p, tree *pre_p, tree *post_p)
 	 the address of a call that returns a struct; see
 	 gcc.dg/c99-array-lval-1.c.  The gimplifier will correctly make
 	 the implied temporary explicit.  */
+
+      /* Mark the RHS addressable.  */
       ret = gimplify_expr (&TREE_OPERAND (expr, 0), pre_p, post_p,
 			   is_gimple_addressable, fb_either);
       if (ret != GS_ERROR)
@@ -3972,8 +3985,7 @@ gimplify_addr_expr (tree *expr_p, tree *pre_p, tree *post_p)
 	     is set properly.  */
 	  recompute_tree_invariant_for_addr_expr (expr);
 
-	  /* Mark the RHS addressable.  */
-	  lang_hooks.mark_addressable (TREE_OPERAND (expr, 0));
+	  mark_addressable (TREE_OPERAND (expr, 0));
 	}
       break;
     }
@@ -4011,7 +4023,7 @@ gimplify_asm_expr (tree *expr_p, tree *pre_p, tree *post_p)
 			       &allows_mem, &allows_reg, &is_inout);
 
       if (!allows_reg && allows_mem)
-	lang_hooks.mark_addressable (TREE_VALUE (link));
+	mark_addressable (TREE_VALUE (link));
 
       tret = gimplify_expr (&TREE_VALUE (link), pre_p, post_p,
 			    is_inout ? is_gimple_min_lval : is_gimple_lvalue,
@@ -4140,7 +4152,7 @@ gimplify_asm_expr (tree *expr_p, tree *pre_p, tree *post_p)
 	{
 	  tret = gimplify_expr (&TREE_VALUE (link), pre_p, post_p,
 				is_gimple_lvalue, fb_lvalue | fb_mayfail);
-	  lang_hooks.mark_addressable (TREE_VALUE (link));
+	  mark_addressable (TREE_VALUE (link));
 	  if (tret == GS_ERROR)
 	    {
 	      error ("memory input %d is not directly addressable", i);
@@ -5562,7 +5574,7 @@ gimplify_expr (tree *expr_p, tree *pre_p, tree *post_p,
 	  if (fallback == fb_lvalue)
 	    {
 	      *expr_p = get_initialized_tmp_var (*expr_p, pre_p, post_p);
-	      lang_hooks.mark_addressable (*expr_p);
+	      mark_addressable (*expr_p);
 	    }
 	  break;
 
@@ -5575,7 +5587,7 @@ gimplify_expr (tree *expr_p, tree *pre_p, tree *post_p,
 	  if (fallback == fb_lvalue)
 	    {
 	      *expr_p = get_initialized_tmp_var (*expr_p, pre_p, post_p);
-	      lang_hooks.mark_addressable (*expr_p);
+	      mark_addressable (*expr_p);
 	    }
 	  break;
 
@@ -5763,7 +5775,7 @@ gimplify_expr (tree *expr_p, tree *pre_p, tree *post_p,
 	  else if (fallback == fb_lvalue)
 	    {
 	      *expr_p = get_initialized_tmp_var (*expr_p, pre_p, post_p);
-	      lang_hooks.mark_addressable (*expr_p);
+	      mark_addressable (*expr_p);
 	    }
 	  else
 	    ret = GS_ALL_DONE;
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 39d7ff0a1b4e..435de150c819 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,7 @@
+2007-06-22  Jan Hubicka  <jh@suse.cz>
+
+	* gcc.c-torture/compile/pr31541.c: New.
+
 2007-06-22  Uros Bizjak  <ubizjak@gmail.com>
 
 	* gcc.target/i386/large-size-array-3.c: Fix dg-do compile directive.
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr31541.c b/gcc/testsuite/gcc.c-torture/compile/pr31541.c
new file mode 100644
index 000000000000..0cac26ed0926
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/pr31541.c
@@ -0,0 +1,9 @@
+typedef unsigned char Uchar;
+struct scsi_mode_header {
+ unsigned char sense_data_len : 8;
+};
+int f(void)
+{
+ struct scsi_mode_header md;
+return *(Uchar*)&md;
+}
-- 
GitLab