* g++.dg/torture/alias-1.C: New test.
authorJakub Jelinek <jakub@redhat.com>
Mon, 4 Feb 2019 08:52:18 +0000 (09:52 +0100)
committerJakub Jelinek <jakub@gcc.gnu.org>
Mon, 4 Feb 2019 08:52:18 +0000 (09:52 +0100)
From-SVN: r268510

gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/torture/alias-1.C [new file with mode: 0644]

index c186df74d4855fb1151900a5f6522c67b7c9ce54..e2b024302c767cd9fb565632ca0b64acdc697cf0 100644 (file)
@@ -1,3 +1,7 @@
+2019-02-04  Jakub Jelinek  <jakub@redhat.com>
+
+       * g++.dg/torture/alias-1.C: New test.
+
 2019-02-03  Martin Sebor  <msebor@redhat.com>
 
        PR c/69661
diff --git a/gcc/testsuite/g++.dg/torture/alias-1.C b/gcc/testsuite/g++.dg/torture/alias-1.C
new file mode 100644 (file)
index 0000000..2abe543
--- /dev/null
@@ -0,0 +1,57 @@
+// Verify we don't try to allocate the same stack slot for
+// buf1 and buf2 in qux.  While there is a CLOBBER stmt for buf1
+// from inlined destructor, the buf1 variable doesn't go out of scope
+// until after the baz call.
+// { dg-do run }
+
+#include <new>
+#include <cstring>
+#include <cstdlib>
+
+char *p;
+struct S { char buf[128]; S () { memset (buf, ' ', 128); }; ~S () {}; };
+
+__attribute__((noipa)) void
+foo (char *x)
+{
+  p = x;
+}
+
+__attribute__((noipa)) int
+bar (S *x)
+{
+  return x->buf[12];
+}
+
+__attribute__((noipa)) void
+baz (char *x)
+{
+  S *a = new (p) (S);
+  S *b = new (x) (S);
+  memset (a->buf, '0', 128);
+  memset (b->buf, '1', 128);
+  if (bar (a) != '0' || bar (b) != '1')
+    abort ();
+  b->~S ();
+  a->~S ();
+}
+
+__attribute__((noipa)) void
+qux ()
+{
+  char buf1[128];
+  foo (buf1);
+  S *p = new (buf1) (S);
+  bar (p);
+  p->~S ();
+  {
+    char buf2[128];
+    baz (buf2);
+  }
+}
+
+int
+main ()
+{
+  qux ();
+}