This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Patch to elide more signed/unsigned warnings


I recently looked at some signed/unsigned warnings in gcc.

calls.c:923: warning: comparison between signed and unsigned
calls.c:923: warning: signed and unsigned type in conditional expression
calls.c:3873: warning: comparison between signed and unsigned
calls.c:3873: warning: signed and unsigned type in conditional expression

They arise from code like this:

MIN (GET_MODE_SIZE (save_mode), BIGGEST_ALIGNMENT / UNITS_PER_WORD)

On Solaris 2.7 it expands to this fun expression:

(((mode_size[(int)(save_mode)]))<((target_flags&0x10000)?128:64)?((mode_size[(int)(save_mode)])):(((!(!(target_flags&0x10000)))?128:64)/((!(!(target_flags&0x10000)))?8:4)))

GCC should be able to determine that the various operands of the
complete expression are non-negative, thus the whole thing is.  The
missing bit of smarts is division.  E.g.:

non-neg-expr1 / non-neg-expr2

So I added handling of *_DIV_EXPR (and while at it *_MOD_EXPR) to
tree_expr_nonnegative_p.  I think in C its only the TRUNC variation,
but I did all of them anyway.  For DIV, its non-neg if both operands
are so, for MOD, its non-neg if the first operand is.

In the process, I found out that I needed to also handle SAVE_EXPR and
NON_LVALUE_EXPR cause gcc transforms the original expressions a bit.
I set both of them to non-neg if the first operand is.

Bootstrapped on solaris2.7 with c,c++,f77.  (Objc is broken at the
moment.)  No regressions and the new testcase passes.

Okay to install?

		--Kaveh


2001-08-21  Kaveh R. Ghazi  <ghazi@caip.rutgers.edu>

	* fold-const.c (tree_expr_nonnegative_p): Handle *_DIV_EXPR,
	*_MOD_EXPR, SAVE_EXPR and NON_LVALUE_EXPR.

testsuite:
	* gcc.dg/compare5.c: New testcase.

diff -rup orig/egcs-CVS20010821/gcc/fold-const.c egcs-CVS20010821/gcc/fold-const.c
--- orig/egcs-CVS20010821/gcc/fold-const.c	Sat Aug 11 21:56:16 2001
+++ egcs-CVS20010821/gcc/fold-const.c	Tue Aug 21 18:28:19 2001
@@ -7397,6 +7397,17 @@ tree_expr_nonnegative_p (t)
       return 1;
     case INTEGER_CST:
       return tree_int_cst_sgn (t) >= 0;
+    case TRUNC_DIV_EXPR:
+    case CEIL_DIV_EXPR:
+    case FLOOR_DIV_EXPR:
+    case ROUND_DIV_EXPR:
+      return tree_expr_nonnegative_p (TREE_OPERAND (t, 0))
+        && tree_expr_nonnegative_p (TREE_OPERAND (t, 1));
+    case TRUNC_MOD_EXPR:
+    case CEIL_MOD_EXPR:
+    case FLOOR_MOD_EXPR:
+    case ROUND_MOD_EXPR:
+      return tree_expr_nonnegative_p (TREE_OPERAND (t, 0));
     case COND_EXPR:
       return tree_expr_nonnegative_p (TREE_OPERAND (t, 1))
 	&& tree_expr_nonnegative_p (TREE_OPERAND (t, 2));
@@ -7412,6 +7423,10 @@ tree_expr_nonnegative_p (t)
       return tree_expr_nonnegative_p (TREE_OPERAND (t, 1));
     case BIND_EXPR:
       return tree_expr_nonnegative_p (TREE_OPERAND (t, 1));
+    case SAVE_EXPR:
+      return tree_expr_nonnegative_p (TREE_OPERAND (t, 0));
+    case NON_LVALUE_EXPR:
+      return tree_expr_nonnegative_p (TREE_OPERAND (t, 0));
     case RTL_EXPR:
       return rtl_expr_nonnegative_p (RTL_EXPR_RTL (t));
       
diff -rup orig/egcs-CVS20010821/gcc/testsuite/gcc.dg/compare5.c egcs-CVS20010821/gcc/testsuite/gcc.dg/compare5.c
--- orig/egcs-CVS20010821/gcc/testsuite/gcc.dg/compare5.c	Tue Aug 21 18:30:55 2001
+++ egcs-CVS20010821/gcc/testsuite/gcc.dg/compare5.c	Tue Aug 21 18:31:44 2001
@@ -0,0 +1,41 @@
+/* Test for a bogus warning on comparison between signed and unsigned.
+   Origin: Kaveh R. Ghazi <ghazi@caip.rutgers.edu> 8/21/2001.  */
+
+/* { dg-do compile } */
+/* { dg-options "-Wsign-compare" } */
+
+extern void bar(void);
+
+int foo(int x, int y, unsigned u)
+{
+  /* A *_DIV_EXPR is non-negative if both operands are.  */
+
+  if (u < ((x=-22)/33)) /* { dg-warning "signed and unsigned" "DIV_EXPR" } */
+    return x;
+
+  if (u < ((x=22)/33))
+    return x;
+
+  if (u < ((x=22)/(y=33)))
+    return x;
+
+  if (u < (((x&0x10000)?128:64) / ((y&0x10000)?8:4)))
+    return x;
+
+
+  /* A *_MOD_EXPR is non-negative if the first operand is.  */
+
+  if (u < ((x=-22)%33)) /* { dg-warning "signed and unsigned" "MOD_EXPR" } */
+    return x;
+
+  if (u < ((x=22)%-33))
+    return x;
+
+  if (u < ((x==y)%-33))
+    return x;
+
+  if (u < (((x=22)/33)%-33))
+    return x;
+
+  return 0;
+}


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]