aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorKaveh R. Ghazi <ghazi@caip.rutgers.edu>2001-05-21 01:21:23 +0000
committerKaveh Ghazi <ghazi@gcc.gnu.org>2001-05-21 01:21:23 +0000
commit88e3805d76d44556e6c07062d62a31e7953b5a6a (patch)
treeb05439e6d5d3e5f22860bee1bfa31706393393c1 /gcc
parent4b404517536c85a092184a540f30d8bd5a496e26 (diff)
downloadgcc-88e3805d76d44556e6c07062d62a31e7953b5a6a.zip
gcc-88e3805d76d44556e6c07062d62a31e7953b5a6a.tar.gz
gcc-88e3805d76d44556e6c07062d62a31e7953b5a6a.tar.bz2
fold-const.c (tree_expr_nonnegative_p): Detect more non-negative cases.
* 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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog5
-rw-r--r--gcc/fold-const.c13
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/g++.old-deja/g++.warn/compare1.C36
-rw-r--r--gcc/testsuite/gcc.dg/compare4.c48
5 files changed, 107 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 1071782..582f100 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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
diff --git a/gcc/fold-const.c b/gcc/fold-const.c
index 3bedea1..2cf534f 100644
--- a/gcc/fold-const.c
+++ b/gcc/fold-const.c
@@ -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:
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 79d4f0a..510cc89 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
index 0000000..687d986
--- /dev/null
+++ b/gcc/testsuite/g++.old-deja/g++.warn/compare1.C
@@ -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
index 0000000..5f567c5
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/compare4.c
@@ -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;
+}