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]

fix 22237


We already had some code that attempted to handle this case, but it
didn't operate properly unless the lhs of the modify_expr is a bare
decl.  Fixed thus.

Tested on powerpc-linux.


r~


        * tree-inline.c (declare_return_variable): Handle modify_dest not
        being a DECL.

Index: gcc/testsuite/gcc.c-torture/execute/builtins/pr22237-lib.c
===================================================================
RCS file: gcc/testsuite/gcc.c-torture/execute/builtins/pr22237-lib.c
diff -N gcc/testsuite/gcc.c-torture/execute/builtins/pr22237-lib.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gcc/testsuite/gcc.c-torture/execute/builtins/pr22237-lib.c	6 Oct 2005 20:44:07 -0000
@@ -0,0 +1,27 @@
+extern void abort (void);
+
+void *
+memcpy (void *dst, const void *src, __SIZE_TYPE__ n)
+{
+  const char *srcp;
+  char *dstp;
+
+  srcp = src;
+  dstp = dst;
+
+  if (dst < src)
+    {
+      if (dst + n > src)
+	abort ();
+    }
+  else
+    {
+      if (src + n > dst)
+	abort ();
+    }
+
+  while (n-- != 0)
+    *dstp++ = *srcp++;
+
+  return dst;
+}
Index: gcc/testsuite/gcc.c-torture/execute/builtins/pr22237.c
===================================================================
RCS file: gcc/testsuite/gcc.c-torture/execute/builtins/pr22237.c
diff -N gcc/testsuite/gcc.c-torture/execute/builtins/pr22237.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gcc/testsuite/gcc.c-torture/execute/builtins/pr22237.c	6 Oct 2005 20:44:07 -0000
@@ -0,0 +1,44 @@
+extern void abort (void);
+extern void exit (int);
+struct s { unsigned char a[256]; };
+union u { struct { struct s b; int c; } d; struct { int c; struct s b; } e; };
+static union u v;
+static union u v0;
+static struct s *p = &v.d.b;
+static struct s *q = &v.e.b;
+
+static inline struct s rp (void) { return *p; }
+static inline struct s rq (void) { return *q; }
+static void pq (void) { *p = rq(); }
+static void qp (void) { *q = rp(); }
+
+static void
+init (struct s *sp)
+{
+  int i;
+  for (i = 0; i < 256; i++)
+    sp->a[i] = i;
+}
+
+static void
+check (struct s *sp)
+{
+  int i;
+  for (i = 0; i < 256; i++)
+    if (sp->a[i] != i)
+      abort ();
+}
+
+void
+main_test (void)
+{
+  v = v0;
+  init (p);
+  qp ();
+  check (q);
+  v = v0;
+  init (q);
+  pq ();
+  check (p);
+  exit (0);
+}
Index: gcc/tree-inline.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-inline.c,v
retrieving revision 1.210
diff -u -p -r1.210 tree-inline.c
--- gcc/tree-inline.c	1 Aug 2005 15:25:28 -0000	1.210
+++ gcc/tree-inline.c	6 Oct 2005 20:44:08 -0000
@@ -1260,10 +1260,21 @@ declare_return_variable (inline_data *id
       /* If the callee cannot possibly modify MODIFY_DEST, then we can
 	 reuse it as the result of the call directly.  Don't do this if
 	 it would promote MODIFY_DEST to addressable.  */
-      else if (!TREE_STATIC (modify_dest)
-	       && !TREE_ADDRESSABLE (modify_dest)
-	       && !TREE_ADDRESSABLE (result))
-	use_it = true;
+      else if (TREE_ADDRESSABLE (result))
+	use_it = false;
+      else
+	{
+	  tree base_m = get_base_address (modify_dest);
+
+	  /* If the base isn't a decl, then it's a pointer, and we don't
+	     know where that's going to go.  */
+	  if (!DECL_P (base_m))
+	    use_it = false;
+	  else if (is_global_var (base_m))
+	    use_it = false;
+	  else if (!TREE_ADDRESSABLE (base_m))
+	    use_it = true;
+	}
 
       if (use_it)
 	{


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