re PR tree-optimization/36400 (points-to results wrong)
authorRichard Biener <rguenth@gcc.gnu.org>
Fri, 27 Jun 2008 21:54:42 +0000 (21:54 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Fri, 27 Jun 2008 21:54:42 +0000 (21:54 +0000)
2008-06-27  Richard Guenther  <rguenther@suse.de>

PR tree-optimization/36400
PR tree-optimization/36373
PR tree-optimization/36344
* tree-ssa-structalias.c (var_escaped, escaped_tree, escaped_id,
var_nonlocal, nonlocal_tree, nonlocal_id): New globals
(update_alias_info): Remove call clobbering code.
(make_constraint_to): New helper function.
(make_escape_constraint): Likewise.
(handle_rhs_call): Use it on all pointer containing arguments.
Also mark the static chain escaped.
(handle_lhs_call): Make constraints from NONLOCAL and ESCAPED
instead of ANYTHING.
(make_constraint_from): New helper split out from ...
(make_constraint_from_anything): ... here.
(find_func_aliases): Add constraints for escape sites.
(intra_create_variable_infos): Make constraints from NONLOCAL
for parameters.
(find_what_p_points_to): Interpret NONLOCAL and ESCAPED the same
as ANYTHING.
(clobber_what_p_points_to): Remove.
(clobber_what_escaped): New function.
(init_base_vars): Init NONLOCAL and ESCAPED.
(do_sd_constraint): Do not propagate the solution from ESCAPED
but use ESCAPED as a placeholder.
(solve_graph): Likewise.
* tree-flow.h (clobber_what_p_points_to): Remove.
(clobber_what_escaped): Declare.
* tree-ssa-alias.c (set_initial_properties): Call it.
Remove code clobbering escaped pointers.

* gcc.dg/torture/pr36373-1.c: New testcase.
* gcc.dg/torture/pr36373-2.c: Likewise.
* gcc.dg/torture/pr36373-3.c: Likewise.
* gcc.dg/torture/pr36373-4.c: Likewise.
* gcc.dg/torture/pr36373-5.c: Likewise.
* gcc.dg/torture/pr36373-6.c: Likewise.
* gcc.dg/torture/pr36373-7.c: Likewise.
* gcc.dg/torture/pr36373-8.c: Likewise.
* gcc.dg/torture/pr36373-9.c: Likewise.
* gcc.dg/torture/pr36373-10.c: Likewise.
* gcc.dg/torture/pr36400.c: Likewise.
* gcc.c-torture/execute/pta-field-1.c: Likewise.
* gcc.c-torture/execute/pta-field-2.c: Likewise.
* gcc.dg/tree-ssa/loadpre8.c: Remove XFAIL.
* gcc.dg/tree-ssa/pr24287.c: XFAIL.

From-SVN: r137204

13 files changed:
gcc/testsuite/gcc.c-torture/execute/pta-field-1.c [new file with mode: 0644]
gcc/testsuite/gcc.c-torture/execute/pta-field-2.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/torture/pr36373-1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/torture/pr36373-10.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/torture/pr36373-2.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/torture/pr36373-3.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/torture/pr36373-4.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/torture/pr36373-5.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/torture/pr36373-6.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/torture/pr36373-7.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/torture/pr36373-8.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/torture/pr36373-9.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/torture/pr36400.c [new file with mode: 0644]

diff --git a/gcc/testsuite/gcc.c-torture/execute/pta-field-1.c b/gcc/testsuite/gcc.c-torture/execute/pta-field-1.c
new file mode 100644 (file)
index 0000000..1377c4b
--- /dev/null
@@ -0,0 +1,28 @@
+struct Foo {
+  int *p;
+  int *q;
+};
+
+void __attribute__((noinline))
+bar (int **x)
+{
+  struct Foo *f = (struct Foo *)x;
+  *(f->q) = 0;
+}
+
+int foo(void)
+{
+  struct Foo f;
+  int i = 1, j = 2;
+  f.p = &i;
+  f.q = &j;
+  bar(&f.p);
+  return j;
+}
+
+extern void abort (void);
+int main()
+{
+  if (foo () != 0)
+    abort ();
+}
diff --git a/gcc/testsuite/gcc.c-torture/execute/pta-field-2.c b/gcc/testsuite/gcc.c-torture/execute/pta-field-2.c
new file mode 100644 (file)
index 0000000..e9b68d0
--- /dev/null
@@ -0,0 +1,28 @@
+struct Foo {
+  int *p;
+  int *q;
+};
+
+void __attribute__((noinline))
+bar (int **x)
+{
+  struct Foo *f = (struct Foo *)(x - 1);
+  *(f->p) = 0;
+}
+
+int foo(void)
+{
+  struct Foo f;
+  int i = 1, j = 2;
+  f.p = &i;
+  f.q = &j;
+  bar(&f.q);
+  return i;
+}
+
+extern void abort (void);
+int main()
+{
+  if (foo () != 0)
+    abort ();
+}
diff --git a/gcc/testsuite/gcc.dg/torture/pr36373-1.c b/gcc/testsuite/gcc.dg/torture/pr36373-1.c
new file mode 100644 (file)
index 0000000..9cd02c5
--- /dev/null
@@ -0,0 +1,35 @@
+/* { dg-do run } */
+/* { dg-options "-fno-tree-sra" } */
+
+extern void abort (void);
+struct Bar {
+    struct Foo {
+       int *p;
+    } x;
+    int *q;
+};
+struct Foo __attribute__((noinline))
+bar(int *p)
+{
+  struct Foo f;
+  f.p = p;
+  return f;
+}
+void __attribute__((noinline))
+foo(struct Foo f)
+{
+  *f.p = 0;
+}
+int main()
+{
+  int a, b;
+  a = 0;
+  b = 1;
+  struct Bar f;
+  f.x = bar (&b);
+  f.q = &a;
+  foo(f.x);
+  if (b != 0)
+    abort ();
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/pr36373-10.c b/gcc/testsuite/gcc.dg/torture/pr36373-10.c
new file mode 100644 (file)
index 0000000..b84e254
--- /dev/null
@@ -0,0 +1,21 @@
+/* { dg-do run } */
+
+typedef unsigned long uintptr_t;
+
+void __attribute__((noinline))
+foo(uintptr_t l)
+{
+  int *p = (int *)l;
+  *p = 1;
+}
+
+extern void abort (void);
+int main()
+{
+  int b = 0;
+  uintptr_t l = (uintptr_t)&b;
+  foo(l);
+  if (b != 1)
+    abort ();
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/pr36373-2.c b/gcc/testsuite/gcc.dg/torture/pr36373-2.c
new file mode 100644 (file)
index 0000000..2653182
--- /dev/null
@@ -0,0 +1,37 @@
+/* { dg-do run } */
+/* { dg-options "-fno-tree-sra" } */
+
+extern void abort (void);
+struct Foo {
+    int *p;
+};
+struct Bar {
+    struct Foo *x;
+    int *q;
+};
+struct Foo __attribute__((noinline))
+bar(int *p)
+{
+  struct Foo f;
+  f.p = p;
+  return f;
+}
+void __attribute__((noinline))
+foo(struct Foo f)
+{
+  *f.p = 0;
+}
+int main()
+{
+  int a, b;
+  a = 0;
+  b = 1;
+  struct Bar f;
+  struct Foo g = bar (&b);
+  f.x = &g;
+  f.q = &a;
+  foo(*f.x);
+  if (b != 0)
+    abort ();
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/pr36373-3.c b/gcc/testsuite/gcc.dg/torture/pr36373-3.c
new file mode 100644 (file)
index 0000000..d5ad93e
--- /dev/null
@@ -0,0 +1,36 @@
+/* { dg-do run } */
+
+extern void abort (void);
+struct Foo {
+    int *p;
+};
+struct Bar {
+    struct Foo *x;
+    int *q;
+};
+struct Foo __attribute__((noinline))
+bar(int *p)
+{
+  struct Foo f;
+  f.p = p;
+  return f;
+}
+void __attribute__((noinline))
+foo(struct Foo f)
+{
+  *f.p = 0;
+}
+int main()
+{
+  int a, b;
+  a = 0;
+  b = 1;
+  struct Bar f;
+  struct Foo g = bar (&b);
+  f.x = &g;
+  f.q = &a;
+  foo(*f.x);
+  if (b != 0)
+    abort ();
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/pr36373-4.c b/gcc/testsuite/gcc.dg/torture/pr36373-4.c
new file mode 100644 (file)
index 0000000..5f3b833
--- /dev/null
@@ -0,0 +1,33 @@
+/* { dg-do run } */
+
+extern void abort (void);
+struct Foo {
+    int *p;
+    int *q;
+};
+struct Foo __attribute__((noinline))
+bar(int *p)
+{
+  struct Foo f;
+  f.p = p;
+  return f;
+}
+void __attribute__((noinline))
+foo(struct Foo f)
+{
+  *f.p = 0;
+}
+int main()
+{
+  int a, b;
+  a = 0;
+  b = 1;
+  struct Foo f;
+  f = bar (&b);
+  f.q = &a;
+  foo(f);
+  if (b != 0)
+    abort ();
+  return 0;
+}
+
diff --git a/gcc/testsuite/gcc.dg/torture/pr36373-5.c b/gcc/testsuite/gcc.dg/torture/pr36373-5.c
new file mode 100644 (file)
index 0000000..0061ef4
--- /dev/null
@@ -0,0 +1,34 @@
+/* { dg-do run } */
+/* { dg-options "-fno-tree-sra" } */
+
+extern void abort (void);
+struct Foo {
+    int *p;
+    int *q;
+};
+struct Foo __attribute__((noinline))
+bar(int *p)
+{
+  struct Foo f;
+  f.p = p;
+  return f;
+}
+void __attribute__((noinline))
+foo(struct Foo f)
+{
+  *f.p = 0;
+}
+int main()
+{
+  int a, b;
+  a = 0;
+  b = 1;
+  struct Foo f;
+  f = bar (&b);
+  f.q = &a;
+  foo(f);
+  if (b != 0)
+    abort ();
+  return 0;
+}
+
diff --git a/gcc/testsuite/gcc.dg/torture/pr36373-6.c b/gcc/testsuite/gcc.dg/torture/pr36373-6.c
new file mode 100644 (file)
index 0000000..c55e3ff
--- /dev/null
@@ -0,0 +1,30 @@
+/* { dg-do run } */
+/* { dg-options "-fno-tree-sra" } */
+
+extern void abort (void);
+struct Foo {
+    int *p;
+} x;
+struct Foo __attribute__((noinline))
+bar(int *p)
+{
+  struct Foo f;
+  f.p = p;
+  return f;
+}
+void __attribute__((noinline))
+foo()
+{
+  *x.p = 0;
+}
+int main()
+{
+  int b;
+  b = 1;
+  struct Foo g = bar (&b);
+  x = g;
+  foo();
+  if (b != 0)
+    abort ();
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/pr36373-7.c b/gcc/testsuite/gcc.dg/torture/pr36373-7.c
new file mode 100644 (file)
index 0000000..103694e
--- /dev/null
@@ -0,0 +1,29 @@
+/* { dg-do run } */
+
+extern void abort (void);
+struct Foo {
+    int *p;
+} x;
+struct Foo __attribute__((noinline))
+bar(int *p)
+{
+  struct Foo f;
+  f.p = p;
+  return f;
+}
+void __attribute__((noinline))
+foo()
+{
+  *x.p = 0;
+}
+int main()
+{
+  int b;
+  b = 1;
+  struct Foo g = bar (&b);
+  x = g;
+  foo();
+  if (b != 0)
+    abort ();
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/pr36373-8.c b/gcc/testsuite/gcc.dg/torture/pr36373-8.c
new file mode 100644 (file)
index 0000000..9f77ea1
--- /dev/null
@@ -0,0 +1,24 @@
+/* { dg-do run } */
+/* { dg-options "-fno-tree-sra" } */
+
+extern void abort (void);
+struct Foo {
+    int *p;
+} x;
+void __attribute__((noinline))
+foo()
+{
+  *x.p = 0;
+}
+int main()
+{
+  int b;
+  struct Foo g;
+  b = 1;
+  g.p = &b;
+  x = g;
+  foo();
+  if (b != 0)
+    abort ();
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/pr36373-9.c b/gcc/testsuite/gcc.dg/torture/pr36373-9.c
new file mode 100644 (file)
index 0000000..5588ead
--- /dev/null
@@ -0,0 +1,23 @@
+/* { dg-do run } */
+
+extern void abort (void);
+struct Foo {
+    int *p;
+} x;
+void __attribute__((noinline))
+foo()
+{
+  *x.p = 0;
+}
+int main()
+{
+  int b;
+  struct Foo g;
+  b = 1;
+  g.p = &b;
+  x = g;
+  foo();
+  if (b != 0)
+    abort ();
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/pr36400.c b/gcc/testsuite/gcc.dg/torture/pr36400.c
new file mode 100644 (file)
index 0000000..bd9f35a
--- /dev/null
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+
+struct barstruct { char const* some_string; };
+
+void changethepointer(struct barstruct***);
+
+void baz()
+{
+  struct barstruct bar1;
+  struct barstruct* barptr = &bar1;
+  struct barstruct** barptr2 = &barptr;
+  changethepointer(&barptr2);
+  barptr->some_string = "Everything OK";
+}
+
+/* { dg-final { scan-assembler "Everything OK" } } */