diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index f81e54d206bc64502a0a548c980f98a038aa153e..efcbdfa946940147924057d6d4caeecebbe40ff0 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2006-05-17  Jakub Jelinek  <jakub@redhat.com>
+
+	PR tree-optimization/27549
+	* g++.dg/tree-ssa/pr27549.C: New test.
+
 2006-05-16  Jerry DeLisle  <jvdelisle@gcc.gnu.org>
 
 	PR libgfortran/27575
diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr27549.C b/gcc/testsuite/g++.dg/tree-ssa/pr27549.C
new file mode 100644
index 0000000000000000000000000000000000000000..2dc98a22019f4b7b70b15b40a6c9883d195f9444
--- /dev/null
+++ b/gcc/testsuite/g++.dg/tree-ssa/pr27549.C
@@ -0,0 +1,78 @@
+// PR tree-optimization/27549
+// { dg-do compile }
+// { dg-options "-O2" }
+
+typedef __SIZE_TYPE__ size_t;
+
+struct E
+{
+  virtual ~E () {}
+  virtual size_t e () const = 0;
+  virtual void f (char *x) const = 0;
+};
+
+struct F : public E
+{
+  virtual ~F () {}
+  virtual size_t e () const { return 0; }
+  virtual void f (char *x) const { *x = '\0'; }
+};
+
+struct S
+{
+  S () { a = new char[32]; b = 32; c = 0; a[0] = 0; }
+  void s (const char *x, size_t y) { v (c + y + 1); __builtin_memcpy(a + c, x, y); c += y; a[c] = '\0'; }
+  void s (const E *x) { size_t l = x->e(); v (c + l + 1); x->f (a + c); c += l; }
+  const char *t () { return a; }
+  void v (size_t n)
+    {
+      if (b >= n) return;
+
+      size_t b2 = b;
+      char *a2 = a;
+
+      for (;;)
+	{
+	  b *= 2;
+	  if (b >= n)
+	    break;
+	}
+
+      a = new char[b];
+
+      if (b2)
+	{
+	  __builtin_memcpy(a, a2, c);
+	  a2[0] = 0;
+	  for (size_t i = 1; i < b2; i++)
+	    a2[i] = a2[i - 1];
+	  delete[] a2;
+	}
+    }
+
+  ~S ()
+    {
+      if (b)
+	{
+	  a[0] = 0;
+	  for (size_t i = 1; i < b; i++)
+	    a[i] = a[i - 1];
+	}
+      delete[] a;
+    }
+  char * a;
+  size_t b, c;
+};
+
+const char *p;
+size_t q;
+const F u;
+
+const char *
+foo ()
+{
+  S s;
+  s.s (p, q);
+  s.s (&u);
+  return s.t ();
+}