fold-const.c (tree_expr_nonnegative_p): Detect more non-negative cases.
authorKaveh R. Ghazi <ghazi@caip.rutgers.edu>
Mon, 21 May 2001 01:21:23 +0000 (01:21 +0000)
committerKaveh Ghazi <ghazi@gcc.gnu.org>
Mon, 21 May 2001 01:21:23 +0000 (01:21 +0000)
* fold-const.c (tree_expr_nonnegative_p): Detect more
non-negative cases.

testsuite:
* g++.old-deja/g++.warn/compare1.C: New test.
* gcc.dg/compare4.c: New test.

From-SVN: r42365

gcc/ChangeLog
gcc/fold-const.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.old-deja/g++.warn/compare1.C [new file with mode: 0644]
gcc/testsuite/gcc.dg/compare4.c [new file with mode: 0644]

index 10717823d7024d8e56ec2e5c201f23914061ac8e..582f100d8f32dbf0ca4bd33719d404469aad7966 100644 (file)
@@ -1,3 +1,8 @@
+2001-05-20  Kaveh R. Ghazi  <ghazi@caip.rutgers.edu>
+
+       * fold-const.c (tree_expr_nonnegative_p): Detect more non-negative
+       cases.
+
 2001-05-21  Joseph S. Myers  <jsm28@cam.ac.uk>
 
        * extend.texi: Clarify documentation of extensions included in ISO
index 3bedea13a78895533e0c1756178cdbc47224e462..2cf534f865338ba0c81419e5ce8fcb4a65839f36 100644 (file)
@@ -7351,11 +7351,24 @@ tree_expr_nonnegative_p (t)
 {
   switch (TREE_CODE (t))
     {
+    case ABS_EXPR:
+    case FFS_EXPR:
+      return 1;
     case INTEGER_CST:
       return tree_int_cst_sgn (t) >= 0;
     case COND_EXPR:
       return tree_expr_nonnegative_p (TREE_OPERAND (t, 1))
        && tree_expr_nonnegative_p (TREE_OPERAND (t, 2));
+    case COMPOUND_EXPR:
+      return tree_expr_nonnegative_p (TREE_OPERAND (t, 1));
+    case MIN_EXPR:
+      return tree_expr_nonnegative_p (TREE_OPERAND (t, 0))
+        && tree_expr_nonnegative_p (TREE_OPERAND (t, 1));
+    case MAX_EXPR:
+      return tree_expr_nonnegative_p (TREE_OPERAND (t, 0))
+        || tree_expr_nonnegative_p (TREE_OPERAND (t, 1));
+    case MODIFY_EXPR:
+      return tree_expr_nonnegative_p (TREE_OPERAND (t, 1));
     case BIND_EXPR:
       return tree_expr_nonnegative_p (TREE_OPERAND (t, 1));
     case RTL_EXPR:
index 79d4f0a763f4e1f84774aa2f1adf5e8a5b92ed49..510cc896e8e2191e8a10a81ec85405b8e0f098e8 100644 (file)
@@ -1,3 +1,8 @@
+2001-05-20  Kaveh R. Ghazi  <ghazi@caip.rutgers.edu>
+
+       * g++.old-deja/g++.warn/compare1.C: New test.
+       * gcc.dg/compare4.c: New test.
+
 2001-05-20  Nathan Sidwell  <nathan@codesourcery.com>
 
        * g++.old-deja/g++.other/optimize1.C: New test.
diff --git a/gcc/testsuite/g++.old-deja/g++.warn/compare1.C b/gcc/testsuite/g++.old-deja/g++.warn/compare1.C
new file mode 100644 (file)
index 0000000..687d986
--- /dev/null
@@ -0,0 +1,36 @@
+// Build don't link:
+// Special g++ Options: -ansi -pedantic-errors -Wsign-compare
+
+// Copyright (C) 2001 Free Software Foundation, Inc.
+// Contributed by Kaveh R. Ghazi <ghazi@caip.rutgers.edu> 5/13/2001
+
+int foo(int x, int y, unsigned u)
+{
+  /* A MAX_EXPR is non-negative if EITHER argument to the MAX_EXPR is
+     determined to be non-negative.  */
+  if (u < (x >? -1)) // WARNING - signed and unsigned
+    return x;
+  if (u < (x >? 10))
+    return x;
+  if ((10 >? x) < u)
+    return x;
+  if (u < (x >? (y ? (x==y) : 10)))
+    return x;
+  if (((y ? 10 : (x==y)) >? x) < u)
+    return x;
+
+  /* A MIN_EXPR is non-negative if BOTH arguments to the MIN_EXPR are
+     determined to be non-negative.  */
+  if (u < ((x?11:8) <? -1)) // WARNING - signed and unsigned
+    return x;
+  if (u < ((x?11:8) <? 10))
+    return x;
+  if ((10 <? (x?8:11)) < u)
+    return x;
+  if (u < ((x?11:(x==y)) <? 10))
+    return x;
+  if ((10 <? (x?(x==y):11)) < u)
+    return x;
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/compare4.c b/gcc/testsuite/gcc.dg/compare4.c
new file mode 100644 (file)
index 0000000..5f567c5
--- /dev/null
@@ -0,0 +1,48 @@
+/* Test for a bogus warning on comparison between signed and unsigned.
+   Origin: Kaveh R. Ghazi <ghazi@caip.rutgers.edu> 5/13/2001.  */
+
+/* { dg-do compile } */
+/* { dg-options "-Wsign-compare" } */
+
+extern void bar(void);
+
+int foo(int x, int y, unsigned u)
+{
+  /* A COMPOUND_EXPR is non-negative if the last element is known to
+     be non-negative.  */
+  if (u < (bar(), -1)) /*{ dg-warning "signed and unsigned" "COMPOUND_EXPR" }*/
+    return x;
+  if (u < (bar(), 10))
+    return x;
+  if ((bar(), 10) < u)
+    return x;
+  if (u < (x ? (bar(),bar(),bar(),bar(),x==y) : 10))
+    return x;
+  if ((x ? 10 : (bar(),bar(),bar(),bar(),x==y)) < u)
+    return x;
+
+  /* Test an ABS_EXPR, which is by definition non-negative.  */
+  if (u < __builtin_abs(x))
+    return x;
+  if (__builtin_abs(x) < u)
+    return x;
+  if (u < (x ? __builtin_abs(x) : 10))
+    return x;
+  if ((x ? 10: __builtin_abs(x)) < u)
+    return x;
+
+  /* A MODIFY_EXPR is non-negative if the new value is known to be
+     non-negative.  */
+  if (u < (x = -1)) /* { dg-warning "signed and unsigned" "MODIFY_EXPR" } */
+    return x;
+  if (u < (x = 10))
+    return x;
+  if ((x = 10) < u)
+    return x;
+  if (u < (x = (y ? (x==y) : 10)))
+    return x;
+  if ((x = (y ? 10 : (x==y))) < u)
+    return x;
+
+  return 0;
+}