OSDN Git Service

2010-05-01 Richard Guenther <rguenther@suse.de>
authorrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 1 May 2010 21:30:26 +0000 (21:30 +0000)
committerrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 1 May 2010 21:30:26 +0000 (21:30 +0000)
PR tree-optimization/43949
* tree-vrp.c (ssa_name_nonnegative_p): Return true for unsigned
types.
(extract_range_from_binary_expr): Handle *_MOD_EXPR.

* g++.dg/warn/Warray-bounds-5.C: New testcase.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@158965 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/warn/Warray-bounds-5.C [new file with mode: 0644]
gcc/tree-vrp.c

index f978694..7f636b3 100644 (file)
@@ -1,3 +1,10 @@
+2010-05-01  Richard Guenther  <rguenther@suse.de>
+
+       PR tree-optimization/43949
+       * tree-vrp.c (ssa_name_nonnegative_p): Return true for unsigned
+       types.
+       (extract_range_from_binary_expr): Handle *_MOD_EXPR.
+
 2010-05-01  Anatoly Sokolov  <aesok@post.ru>
 
        * rtl.h (CONST_DOUBLE_P): Define.
index 8e1b484..39a8d97 100644 (file)
@@ -1,3 +1,8 @@
+2010-05-01  Richard Guenther  <rguenther@suse.de>
+
+       PR tree-optimization/43949
+       * g++.dg/warn/Warray-bounds-5.C: New testcase.
+
 2010-05-01  H.J. Lu  <hongjiu.lu@intel.com>
 
        PR c++/43951
diff --git a/gcc/testsuite/g++.dg/warn/Warray-bounds-5.C b/gcc/testsuite/g++.dg/warn/Warray-bounds-5.C
new file mode 100644 (file)
index 0000000..06d776a
--- /dev/null
@@ -0,0 +1,24 @@
+// { dg-do compile }
+// { dg-options "-O2 -Warray-bounds" }
+
+void f();
+
+int c[3];
+int result;
+
+struct Vector {
+    static int get(int i) {
+        if (i >= 3)
+            f();
+        return c[i];
+    }
+};
+
+void g()
+{
+    for (int i = 0; i < 3; ++i) {
+        const int index = i % 3;
+        result = Vector::get(index) + Vector::get(index);
+    }
+}
+
index d8ebbe8..83ff665 100644 (file)
@@ -1364,6 +1364,10 @@ ssa_name_nonnegative_p (const_tree t)
 {
   value_range_t *vr = get_value_range (t);
 
+  if (INTEGRAL_TYPE_P (t)
+      && TYPE_UNSIGNED (t))
+    return true;
+
   if (!vr)
     return false;
 
@@ -2079,6 +2083,10 @@ extract_range_from_binary_expr (value_range_t *vr,
       && code != CEIL_DIV_EXPR
       && code != EXACT_DIV_EXPR
       && code != ROUND_DIV_EXPR
+      && code != TRUNC_MOD_EXPR
+      && code != FLOOR_MOD_EXPR
+      && code != CEIL_MOD_EXPR
+      && code != ROUND_MOD_EXPR
       && code != RSHIFT_EXPR
       && code != MIN_EXPR
       && code != MAX_EXPR
@@ -2147,6 +2155,10 @@ extract_range_from_binary_expr (value_range_t *vr,
       && code != CEIL_DIV_EXPR
       && code != EXACT_DIV_EXPR
       && code != ROUND_DIV_EXPR
+      && code != TRUNC_MOD_EXPR
+      && code != FLOOR_MOD_EXPR
+      && code != CEIL_MOD_EXPR
+      && code != ROUND_MOD_EXPR
       && (vr0.type == VR_VARYING
          || vr1.type == VR_VARYING
          || vr0.type != vr1.type
@@ -2497,6 +2509,28 @@ extract_range_from_binary_expr (value_range_t *vr,
            }
        }
     }
+  else if (code == TRUNC_MOD_EXPR
+          || code == FLOOR_MOD_EXPR
+          || code == CEIL_MOD_EXPR
+          || code == ROUND_MOD_EXPR)
+    {
+      bool sop = false;
+      if (vr0.type == VR_ANTI_RANGE
+         || vr1.type != VR_RANGE
+         || symbolic_range_p (&vr1)
+         || range_includes_zero_p (&vr1))
+       {
+         set_value_range_to_varying (vr);
+         return;
+       }
+      type = VR_RANGE;
+      max = int_const_binop (MINUS_EXPR, vr1.max, integer_one_node, 0);
+      if (vrp_expr_computes_nonnegative (op0, &sop)
+         && vrp_expr_computes_nonnegative (op1, &sop) && !sop)
+       min = build_int_cst (TREE_TYPE (vr1.max), 0);
+      else
+       min = fold_unary (NEGATE_EXPR, TREE_TYPE (max), max);
+    }
   else if (code == MINUS_EXPR)
     {
       /* If we have a MINUS_EXPR with two VR_ANTI_RANGEs, drop to