]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR tree-optimization/22071 (ICE in first_vi_for_offset, at tree-ssa-structalias...
authorDaniel Berlin <dberlin@dberlin.org>
Fri, 1 Jul 2005 19:45:23 +0000 (19:45 +0000)
committerDaniel Berlin <dberlin@gcc.gnu.org>
Fri, 1 Jul 2005 19:45:23 +0000 (19:45 +0000)
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.

From-SVN: r101516

gcc/ChangeLog
gcc/testsuite/g++.dg/tree-ssa/pr22071.C [new file with mode: 0644]
gcc/tree-ssa-structalias.c

index 37b484df4bcd44f5c534fd45e63f997f508b51b6..70be419535677b6749d5eba1b85c264a8fdaf600 100644 (file)
@@ -1,3 +1,11 @@
+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.
+
 2005-07-01  Andrew Pinski  <pinskia@physics.uc.edu>
 
        PR other/22264
diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr22071.C b/gcc/testsuite/g++.dg/tree-ssa/pr22071.C
new file mode 100644 (file)
index 0000000..719aed3
--- /dev/null
@@ -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 61137aaa63d6952c83cf46cc89169ae9a9602b5a..06adb3ec60202bd7cedbae691868c33aa1267b37 100644 (file)
@@ -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");