re PR tree-optimization/15262 ([tree-ssa] Alias analyzer cannot handle addressable...
authorAndrew Pinski <apinski@apple.com>
Mon, 23 Aug 2004 03:12:38 +0000 (03:12 +0000)
committerAndrew Pinski <pinskia@gcc.gnu.org>
Mon, 23 Aug 2004 03:12:38 +0000 (20:12 -0700)
2004-08-22  Andrew Pinski  <apinski@apple.com>

       PR c/15262
       * c-typeck.c (build_unary_op): Use &a.b if the foldded lowered
       expression is not constant.
       (c_finish_return): Do not go through INDIRECT_REF when looking
       for the inner expression of an ADDR_EXPR for warning about.

2004-08-22  Andrew Pinski  <apinski@apple.com>

       * g++.dg/opt/pr14029.C: New test.
       * gcc.c-torture/execute/pr15262.c: New test.
2004-08-22  Andrew Pinski  <apinski@apple.com>

       PR c++/14029
       * typeck.c (build_unary_op): Use &a.b if the foldded lowered
       expression is not constant.

From-SVN: r86396

gcc/ChangeLog
gcc/c-typeck.c
gcc/cp/ChangeLog
gcc/cp/typeck.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/opt/pr14029.C [new file with mode: 0644]
gcc/testsuite/gcc.c-torture/execute/pr15262.c [new file with mode: 0644]

index 99864a89aa6457aad823eb86d6e18cafff658778..94756947a4e0661ec28933b8af7b17fad0feef5b 100644 (file)
@@ -1,3 +1,11 @@
+2004-08-22  Andrew Pinski  <apinski@apple.com>
+
+       PR c/15262
+       * c-typeck.c (build_unary_op): Use &a.b if the foldded lowered
+       expression is not constant.
+       (c_finish_return): Do not go through INDIRECT_REF when looking
+       for the inner expression of an ADDR_EXPR for warning about.
+
 2004-08-22  Richard Henderson  <rth@redhat.com>
 
        PR 17075
index ad8acee710db1bcd8f26fc0e201e4a04fb4a6996..3530c20868a17e9227432b815eb4b85f5f350063 100644 (file)
@@ -2538,9 +2538,14 @@ build_unary_op (enum tree_code code, tree xarg, int flag)
            addr = fold (build2 (PLUS_EXPR, argtype,
                                 convert (argtype, addr),
                                 convert (argtype, byte_position (field))));
+           
+           /* If the folded PLUS_EXPR is not a constant address, wrap
+               it in an ADDR_EXPR.  */
+           if (!TREE_CONSTANT (addr))
+             addr = build1 (ADDR_EXPR, argtype, arg);
          }
        else
-         addr = build1 (code, argtype, arg);
+         addr = build1 (ADDR_EXPR, argtype, arg);
 
        if (TREE_CODE (arg) == COMPOUND_LITERAL_EXPR)
          TREE_INVARIANT (addr) = TREE_CONSTANT (addr) = 1;
@@ -6310,7 +6315,8 @@ c_finish_return (tree retval)
            case ADDR_EXPR:
              inner = TREE_OPERAND (inner, 0);
 
-             while (TREE_CODE_CLASS (TREE_CODE (inner)) == 'r')
+             while (TREE_CODE_CLASS (TREE_CODE (inner)) == 'r'
+                    && TREE_CODE (inner) != INDIRECT_REF)
                inner = TREE_OPERAND (inner, 0);
 
              if (DECL_P (inner)
index c0f488e94a229e81aedee84e0fdb02184c496e09..e2b32126ce06ff818d74da873bd2d15830526eb8 100644 (file)
@@ -1,3 +1,9 @@
+2004-08-22  Andrew Pinski  <apinski@apple.com>
+
+       PR c++/14029
+       * typeck.c (build_unary_op): Use &a.b if the foldded lowered
+       expression is not constant.
+
 2004-08-20  Mark Mitchell  <mark@codesourcery.com>
 
        PR c++/17121
index 01b969edb97e9f6e989bceb44bf4e09ae0919d51..a614db58978e3f470549137b02f1ed7f51936040 100644 (file)
@@ -4123,6 +4123,11 @@ build_unary_op (enum tree_code code, tree xarg, int noconvert)
            addr = fold (build2 (PLUS_EXPR, argtype, rval,
                                 cp_convert (argtype,
                                             byte_position (field))));
+
+           /* If the folded PLUS_EXPR is not a constant address, wrap
+               it in an ADDR_EXPR.  */
+           if (!TREE_CONSTANT (addr))
+             addr = build_address (arg);
          }
 
        if (TREE_CODE (argtype) == POINTER_TYPE
index 0bf7dfb0af53299420ee9e8b8c79873a3cb7e268..23d0604c2de84cb973b680c95ea9b41a3cc2eed8 100644 (file)
@@ -1,3 +1,8 @@
+2004-08-22  Andrew Pinski  <apinski@apple.com>
+
+       * g++.dg/opt/pr14029.C: New test.
+       * gcc.c-torture/execute/pr15262.c: New test.
+
 2004-08-22  Tobias Schlueter  <tobias.schlueter@physik.uni-muenchen.de>
 
        * gfortran.dg/reduction.f90: Add checks with complex arguments.
diff --git a/gcc/testsuite/g++.dg/opt/pr14029.C b/gcc/testsuite/g++.dg/opt/pr14029.C
new file mode 100644 (file)
index 0000000..1673edf
--- /dev/null
@@ -0,0 +1,41 @@
+// { dg-do run }
+// { dg-options "-O2" }
+// We used to mis-compile this testcase as we did not know that
+// &a+offsetof(b,a) was the same as &a.b
+
+struct Iterator {
+    int * ptr;
+
+    Iterator(int * i) : ptr(i) { }
+    void operator++() { ++ptr; }
+    int *const & base() const { return ptr; }
+};
+
+
+Iterator find_7(Iterator first, Iterator last)
+{
+  int trip_count  = (last.base() - first.base()) >> 1;
+
+  for ( ; trip_count > 0 ; --trip_count) {
+    if (*first.ptr == 7) return first;
+    ++first;
+
+    if (*first.ptr == 7) return first;
+    ++first;
+  }
+
+  switch(last.base() - first.base()) {
+    case 1:
+          if (*first.ptr == 7) return first;
+          ++first;
+    case 0:
+    default:
+          return last;
+  }
+}
+
+int main() {
+  int as[5] = {4,4,4,4,7};
+  return (find_7(Iterator(&as[0]), Iterator(&as[5])).ptr == &as[5]);
+};
+
diff --git a/gcc/testsuite/gcc.c-torture/execute/pr15262.c b/gcc/testsuite/gcc.c-torture/execute/pr15262.c
new file mode 100644 (file)
index 0000000..2110f33
--- /dev/null
@@ -0,0 +1,48 @@
+/* We used to mis-compile this testcase as we did not know that
+   &a+offsetof(b,a) was the same as &a.b */
+struct A
+{
+  int t;
+  int i;
+};
+
+void
+bar (float *p)
+{
+  *p = 5.2;
+}
+
+int
+foo(struct A *locp, int i, int str)
+{
+  float f, g, *p;
+  int T355;
+  int *T356;
+  /* Currently, the alias analyzer has limited support for handling
+     aliases of structure fields when no other variables are aliased.
+     Introduce additional aliases to confuse it.  */
+  p =  i ? &g : &f;
+  bar (p);
+  if (*p > 0.0)
+    str = 1;
+
+  T355 = locp->i;
+  T356 = &locp->i;
+  *T356 = str;
+  T355 = locp->i;
+
+  return T355;
+}
+
+main ()
+{
+  struct A loc;
+  int str;
+
+  loc.i = 2;
+  str = foo (&loc, 10, 3);
+  if (str!=1)
+    abort ();
+  return 0;
+}
+