diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 05eec8880f6f802e240e342c808b059eb8749d1c..c52ca2be3b8ef79ae6723e9c7f50ff0e83417814 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,11 @@
+2010-04-20  Richard Guenther  <rguenther@suse.de>
+
+	* tree-ssa-structalias.c (do_structure_copy): Properly handle
+	DEREF.
+	(dump_sa_points_to_info): Remove asserts.
+	(init_base_vars): nothing_id isn't an escape point nor does it
+	have pointers.
+
 2010-04-20  Jakub Jelinek  <jakub@redhat.com>
 
 	* tree.h (TYPE_REF_IS_RVALUE): Define.
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index f4797822eade04b067dc828c0e13cf3f01068f3d..08619dac9522f16cda3f85ee055f1176f1686412 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,7 @@
+2010-04-20  Richard Guenther  <rguenther@suse.de>
+
+	* gcc.dg/ipa/ipa-pta-14.c: New testcase.
+
 2010-04-20  Jakub Jelinek  <jakub@redhat.com>
 
 	* g++.dg/debug/dwarf2/rv1.C: New test.
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-pta-14.c b/gcc/testsuite/gcc.dg/ipa/ipa-pta-14.c
new file mode 100644
index 0000000000000000000000000000000000000000..ffe16ccc358a5a76c53d936c79e42dbf38530afd
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-pta-14.c
@@ -0,0 +1,32 @@
+/* { dg-do run } */
+/* { dg-options "-O2 -fipa-pta -fno-tree-sra -fdump-ipa-pta-details" } */
+
+struct X {
+    int i;
+    void *p;
+};
+
+static void * __attribute__((noinline,noclone))
+foo(struct X *q, void *p)
+{
+  struct X b;
+  b.p = p;
+  *q = b;
+  return q->p;
+}
+extern void abort (void);
+int main()
+{
+  struct X a, c;
+  void *p;
+  a.p = (void *)&c;
+  p = foo(&a, &a);
+  /* { dg-final { scan-ipa-dump "foo.result = { NULL a c }" "pta" { xfail *-*-* } } } */
+  /* { dg-final { scan-ipa-dump "foo.result = { NULL a a\[^ \]* c }" "pta" } } */
+  ((struct X *)p)->p = (void *)0;
+  if (a.p != (void *)0)
+    abort ();
+  return 0;
+}
+
+/* { dg-final { cleanup-ipa-dump "pta" } } */
diff --git a/gcc/tree-ssa-structalias.c b/gcc/tree-ssa-structalias.c
index ad4c10d326127bd918009919de3c48139bc23053..781eff30872cb3dfdda97e1988a1c820544f841f 100644
--- a/gcc/tree-ssa-structalias.c
+++ b/gcc/tree-ssa-structalias.c
@@ -3403,7 +3403,19 @@ do_structure_copy (tree lhsop, tree rhsop)
   if (lhsp->type == DEREF
       || (lhsp->type == ADDRESSOF && lhsp->var == anything_id)
       || rhsp->type == DEREF)
-    process_all_all_constraints (lhsc, rhsc);
+    {
+      if (lhsp->type == DEREF)
+	{
+	  gcc_assert (VEC_length (ce_s, lhsc) == 1);
+	  lhsp->offset = UNKNOWN_OFFSET;
+	}
+      if (rhsp->type == DEREF)
+	{
+	  gcc_assert (VEC_length (ce_s, rhsc) == 1);
+	  rhsp->offset = UNKNOWN_OFFSET;
+	}
+      process_all_all_constraints (lhsc, rhsc);
+    }
   else if (lhsp->type == SCALAR
 	   && (rhsp->type == SCALAR
 	       || rhsp->type == ADDRESSOF))
@@ -5910,13 +5922,7 @@ dump_sa_points_to_info (FILE *outfile)
     {
       varinfo_t vi = get_varinfo (i);
       if (!vi->may_have_pointers)
-	{
-	  gcc_assert (find (i) == i
-		      || !(vi = get_varinfo (find (i)))->may_have_pointers);
-	  /* ???  See create_variable_info_for.
-	     gcc_assert (bitmap_empty_p (vi->solution));  */
-	  continue;
-	}
+	continue;
       dump_solution_for_var (outfile, i);
     }
 }
@@ -5955,6 +5961,8 @@ init_base_vars (void)
   var_nothing->size = ~0;
   var_nothing->fullsize = ~0;
   var_nothing->is_special_var = 1;
+  var_nothing->may_have_pointers = 0;
+  var_nothing->is_global_var = 0;
 
   /* Create the ANYTHING variable, used to represent that a variable
      points to some unknown piece of memory.  */