re PR tree-optimization/20601 (PRE related miscompilation)
authorDaniel Berlin <dberlin@dberlin.org>
Wed, 23 Mar 2005 18:14:48 +0000 (18:14 +0000)
committerDaniel Berlin <dberlin@gcc.gnu.org>
Wed, 23 Mar 2005 18:14:48 +0000 (18:14 +0000)
2005-03-23  Daniel Berlin  <dberlin@dberlin.org>

Fix PR tree-optimization/20601

* tree-ssa-pre.c (insert_aux): Add missing condition to
constification.

From-SVN: r96937

gcc/ChangeLog
gcc/testsuite/gcc.dg/tree-ssa/pr20601.c [new file with mode: 0644]
gcc/tree-ssa-pre.c

index 36c07b8875643be65e8c632d6144bfd3eabd0e71..ee38559c8d1e887a0a641e949f2dc5a2079de8a1 100644 (file)
@@ -1,3 +1,10 @@
+2005-03-23  Daniel Berlin  <dberlin@dberlin.org>
+
+       Fix PR tree-optimization/20601
+
+       * tree-ssa-pre.c (insert_aux): Add missing condition to
+       constification.
+
 2005-03-23  Ian Lance Taylor  <ian@airs.com>
 
        * final.c (final_scan_insn): Don't remove no-op instructions.
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr20601.c b/gcc/testsuite/gcc.dg/tree-ssa/pr20601.c
new file mode 100644 (file)
index 0000000..f7b93b7
--- /dev/null
@@ -0,0 +1,123 @@
+/* { dg-do run } */
+/* { dg-options "-O2" } */
+extern void abort (void);
+extern void exit (int);
+
+struct T
+{
+  char *t1;
+  char t2[4096];
+  char **t3;
+};
+
+int a[5];
+int b;
+char **c;
+int d;
+char **e;
+struct T t;
+char *f[16];
+char *g[] = { "a", "-u", "b", "c" };
+
+__attribute__ ((__noreturn__)) void
+foo (void)
+{
+  while (1);
+}
+
+__attribute__ ((noinline)) char *
+bar (char *x, unsigned int y)
+{
+  return 0;
+}
+
+static inline char *
+baz (char *x, unsigned int y)
+{
+  if (sizeof (t.t2) != (unsigned int) -1 && y > sizeof (t.t2))
+    foo ();
+  return bar (x, y);
+}
+
+static inline int
+setup1 (int x)
+{
+  char *p;
+  int rval;
+
+  if (!baz (t.t2, sizeof (t.t2)))
+    baz (t.t2, sizeof (t.t2));
+
+  if (x & 0x200)
+    {
+      char **h, **i = e;
+
+      ++d;
+      e = f;
+      if (t.t1 && *t.t1)
+        e[0] = t.t1;
+      else
+        abort ();
+
+      for (h = e + 1; (*h = *i); ++i, ++h)
+        ;
+    }
+  return 1;
+}
+
+static inline int
+setup2 (void)
+{
+  int j = 1;
+
+  e = c + 1;
+  d = b - 1;
+  while (d > 0 && e[0][0] == '-')
+    {
+      if (e[0][1] != '\0' && e[0][2] != '\0')
+        abort ();
+
+      switch (e[0][1])
+        {
+        case 'u':
+          if (!e[1])
+            abort ();
+
+          t.t3 = &e[1];
+          d--;
+          e++;
+          break;
+        case 'P':
+          j |= 0x1000;
+          break;
+        case '-':
+          d--;
+          e++;
+          if (j == 1)
+            j |= 0x600;
+          return j;
+        }
+      d--;
+      e++;
+    }
+
+  if (d > 0 && !(j & 1))
+    abort ();
+
+  return j;
+}
+
+int
+main (void)
+{
+  int x;
+  c = g;
+  b = 4;
+  x = setup2 ();
+  t.t1 = "/bin/sh";
+  setup1 (x);
+  /* PRE shouldn't transform x into the constant 0x601 here, it's not legal.  */
+  if ((x & 0x400) && !a[4])
+    abort ();
+  exit (0);
+}
index 161d7e5a12c7481b5543ca34bca246ad7037ffad..5593c001dc5eedd9ff62062efb5eecf6e66fdc49 100644 (file)
@@ -1670,7 +1670,7 @@ insert_aux (basic_block block)
                      /* If all edges produce the same value and that value is
                         an invariant, then the PHI has the same value on all
                         edges.  Note this.  */
-                     else if (all_same && eprime 
+                     else if (!cant_insert && all_same && eprime 
                               && is_gimple_min_invariant (eprime)
                               && !is_gimple_min_invariant (val))
                        {