This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Fix PR43949
- From: Richard Guenther <rguenther at suse dot de>
- To: gcc-patches at gcc dot gnu dot org
- Cc: ebotcazou at adacore dot com
- Date: Fri, 30 Apr 2010 23:32:08 +0200 (CEST)
- Subject: [PATCH] Fix PR43949
This fixes PR43949, a false -Warray-bounds because we do not handle
*_MOD_EXPRs at all in VRP.
Bootstrapped and tested on x86_64-unknown-linux-gnu. Bootstrap
of Ada fails but the testsuite is clean when not bootstrapping.
Can someone investigate (or spot the obvious error)? Bootstrap
fails with warnings about types not in range.
Thanks,
Richard.
2010-04-30 Richard Guenther <rguenther@suse.de>
PR tree-optimization/43949
* tree-vrp.c (extract_range_from_binary_expr): Handle *_MOD_EXPR.
* g++.dg/warn/Warray-bounds-5.C: New testcase.
Index: gcc/testsuite/g++.dg/warn/Warray-bounds-5.C
===================================================================
*** gcc/testsuite/g++.dg/warn/Warray-bounds-5.C (revision 0)
--- gcc/testsuite/g++.dg/warn/Warray-bounds-5.C (revision 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: gcc/tree-vrp.c
===================================================================
*** gcc/tree-vrp.c (revision 158944)
--- gcc/tree-vrp.c (working copy)
*************** extract_range_from_binary_expr (value_ra
*** 2079,2084 ****
--- 2079,2088 ----
&& 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
*************** extract_range_from_binary_expr (value_ra
*** 2147,2152 ****
--- 2151,2160 ----
&& 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
*************** extract_range_from_binary_expr (value_ra
*** 2497,2502 ****
--- 2505,2527 ----
}
}
}
+ else if (code == TRUNC_MOD_EXPR
+ || code == FLOOR_MOD_EXPR
+ || code == CEIL_MOD_EXPR
+ || code == ROUND_MOD_EXPR)
+ {
+ if (vr0.type == VR_ANTI_RANGE
+ || vr1.type != VR_RANGE
+ || symbolic_range_p (&vr1)
+ || compare_values (vr1.min, integer_zero_node) != 1)
+ {
+ set_value_range_to_varying (vr);
+ return;
+ }
+ type = VR_RANGE;
+ min = build_int_cst (TREE_TYPE (vr1.max), 0);
+ max = int_const_binop (MINUS_EXPR, vr1.max, integer_one_node, 0);
+ }
else if (code == MINUS_EXPR)
{
/* If we have a MINUS_EXPR with two VR_ANTI_RANGEs, drop to