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]: Fix tree-optimization/22071


This is a bug where we take the address of part of a structure, and the
part we are taking the address of actually begins in the padding.  This
has no real field associated with the starting offset, which confuses
the structure alias analyzer.

Fixed by finding the first real overlapping field for the access, which
should cover the non-padding part of the access for the structures we
handle.

I have a bad feeling in the pit of my stomach that this is going to pop
up again because of some other corner case, and we are going to need to
do a little work to redesign how we handle some of the constraint
generation.

But for now, I've simply pushed that feeling down further and fixed the
bug.

We shall see what happens.

This is currently finishing regtest on i686-pc-linux-gnu.
I will commit once it succeeds.

2005-06-29  Daniel Berlin  <dberlin@dberlin.org>

	Fix PR tree-optimization/22071

	* tree-ssa-structalias.c (offset_overlaps_with_access): New
	function.
	(get_constraint_for_component_ref): Use it.

Index: tree-ssa-structalias.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-ssa-structalias.c,v
retrieving revision 2.6
diff -u -p -r2.6 tree-ssa-structalias.c
--- tree-ssa-structalias.c	25 Jun 2005 02:01:47 -0000	2.6
+++ tree-ssa-structalias.c	29 Jun 2005 15:17:47 -0000
@@ -1940,6 +1940,25 @@ bitpos_of_field (const tree fdecl)
 }
 
 
+/* Return true if an access to [ACCESSPOS, ACCESSSIZE]
+   overlaps with a field at [FIELDPOS, FIELDSIZE] */
+
+static bool
+offset_overlaps_with_access (const unsigned HOST_WIDE_INT fieldpos,
+			     const unsigned HOST_WIDE_INT fieldsize,
+			     const unsigned HOST_WIDE_INT accesspos,
+			     const unsigned HOST_WIDE_INT accesssize)
+{
+  if (fieldpos == accesspos && fieldsize == accesssize)
+    return true;
+  if (accesspos >= fieldpos && accesspos <= (fieldpos + fieldsize))
+    return true;
+  if (accesspos < fieldpos && (accesspos + accesssize > fieldpos))
+    return true;
+  
+  return false;
+}
+
 /* Given a COMPONENT_REF T, return the constraint_expr for it.  */
 
 static struct constraint_expr
@@ -2000,8 +2019,27 @@ get_constraint_for_component_ref (tree t
 	 we may have to do something cute here.  */
       
       if (result.offset < get_varinfo (result.var)->fullsize)	
-	result.var = first_vi_for_offset (get_varinfo (result.var), 
-					  result.offset)->id;
+	{
+	  /* It's also not true that the constraint will actually start at the
+	     right offset, it may start in some padding.  We only care about
+	     setting the constraint to the first actual field it touches, so
+	     walk to find it.  */ 
+	  varinfo_t curr;
+	  for (curr = get_varinfo (result.var); curr; curr = curr->next)
+	    {
+	      if (offset_overlaps_with_access (curr->offset, curr->size,
+					       result.offset, bitsize))
+		{
+		  result.var = curr->id;
+		  break;
+
+		}
+	    }
+	  /* assert that we found *some* field there. The user couldn't be
+	     accessing *only* padding.  */
+	     
+	  gcc_assert (curr);
+	}
       else
 	if (dump_file && (dump_flags & TDF_DETAILS))
 	  fprintf (dump_file, "Access to past the end of variable, ignoring\n");
Index: testsuite/g++.dg/tree-ssa/pr22071.C
===================================================================
RCS file: testsuite/g++.dg/tree-ssa/pr22071.C
diff -N testsuite/g++.dg/tree-ssa/pr22071.C
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ testsuite/g++.dg/tree-ssa/pr22071.C	29 Jun 2005 15:17:53 -0000
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+/* This code ends up taking the address of part of the structure that is padding, 
+   and because there is no real field there, the structure alias analyzer would 
+   abort.  */
+struct empty_class {};
+struct class1 : empty_class
+{
+  class1() {}
+  empty_class value_;
+};
+struct lambda : class1 { };
+lambda _1;

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