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: silence bogus sign-compare warnings on truth values in ?:


I noticed we were getting some bogus sign-compare warnings in
c-common.c.  Looking at the code generating the warnings we have:

 > enum format_std_version { STD_C89, STD_C94, STD_C99, STD_EXT };
 > [...]
 > #define C_STD_VER               (c_language == clk_cplusplus              \
 >                                  ? CPLUSPLUS_STD_VER                      \
 >                                  : (flag_isoc99                           \
 >                                     ? STD_C99                             \
 >                                     : (flag_isoc94 ? STD_C94 : STD_C89)))
 > [...]
 > if (length_chars_std > C_STD_VER)

and we get warnings like this:
 > c-common.c:2904: warning: comparison between signed and unsigned

Normally, tree_expr_nonnegative_p() would allow gcc to figure out that
C_STD_VER is non-negative.  However if you look at the last line of
the definition of C_STD_VER, you'll see a conditional expression which
is really the following once you convert the STD_C* enums into ints.

 > (flag_isoc94 ? 1 : 0)

This appears to get optimized into (flag_isoc94 != 0) and suddenly
tree_expr_nonnegative_p() is not up to the task.

Fixed thus.  Bootstrap/testsuite underway on solaris2.7. Assuming no
regressions, ok to install?

		Thanks,
		--Kaveh


2000-12-17  Kaveh R. Ghazi  <ghazi@caip.rutgers.edu>

	* fold-const.c (tree_expr_nonnegative_p): Treat truth values as
	non-negative.

testsuite:
	* gcc.dg/compare3.c: New test.

diff -rup orig/egcs-CVS20001217/gcc/fold-const.c egcs-CVS20001217/gcc/fold-const.c
--- orig/egcs-CVS20001217/gcc/fold-const.c	Sun Nov 26 10:47:19 2000
+++ egcs-CVS20001217/gcc/fold-const.c	Sun Dec 17 18:49:55 2000
@@ -7299,8 +7299,12 @@ tree_expr_nonnegative_p (t)
       return rtl_expr_nonnegative_p (RTL_EXPR_RTL (t));
       
     default:
-      /* We don't know sign of `t', so be safe and return false.  */
-      return 0;
+      if (truth_value_p (TREE_CODE (t)))
+	/* Truth values evaluate to 0 or 1, which is nonnegative.  */
+	return 1;
+      else
+	/* We don't know sign of `t', so be conservative and return false.  */
+	return 0;
     }
 }
 
diff -rup orig/egcs-CVS20001217/gcc/testsuite/gcc.dg/compare3.c egcs-CVS20001217/gcc/testsuite/gcc.dg/compare3.c
--- orig/egcs-CVS20001217/gcc/testsuite/gcc.dg/compare3.c	Sun Dec 17 18:49:04 2000
+++ egcs-CVS20001217/gcc/testsuite/gcc.dg/compare3.c	Sun Dec 17 19:00:02 2000
@@ -0,0 +1,59 @@
+/* Test for a bogus warning on comparison between signed and unsigned.
+   This was inspired by code in gcc. */
+
+/* { dg-do compile } */
+/* { dg-options "-Wsign-compare" } */
+
+int tf = 1;
+
+void f(int x, unsigned int y)
+{
+  /* Test comparing conditional expressions containing truth values.
+     This can occur explicitly, or e.g. when (foo?2:(bar?1:0)) is
+     optimized into (foo?2:(bar!=0)).  */
+  x > (tf?64:(tf!=x)); /* { dg-bogus "signed and unsigned" "case 1" } */
+  y > (tf?64:(tf!=x)); /* { dg-bogus "signed and unsigned" "case 2" } */
+  x > (tf?(tf!=x):64); /* { dg-bogus "signed and unsigned" "case 3" } */
+  y > (tf?(tf!=x):64); /* { dg-bogus "signed and unsigned" "case 4" } */
+
+  x > (tf?64:(tf==x)); /* { dg-bogus "signed and unsigned" "case 5" } */
+  y > (tf?64:(tf==x)); /* { dg-bogus "signed and unsigned" "case 6" } */
+  x > (tf?(tf==x):64); /* { dg-bogus "signed and unsigned" "case 7" } */
+  y > (tf?(tf==x):64); /* { dg-bogus "signed and unsigned" "case 8" } */
+
+  x > (tf?64:(tf>x)); /* { dg-bogus "signed and unsigned" "case 9" } */
+  y > (tf?64:(tf>x)); /* { dg-bogus "signed and unsigned" "case 10" } */
+  x > (tf?(tf>x):64); /* { dg-bogus "signed and unsigned" "case 11" } */
+  y > (tf?(tf>x):64); /* { dg-bogus "signed and unsigned" "case 12" } */
+
+  x < (tf?64:(tf<x)); /* { dg-bogus "signed and unsigned" "case 13" } */
+  y < (tf?64:(tf<x)); /* { dg-bogus "signed and unsigned" "case 14" } */
+  x < (tf?(tf<x):64); /* { dg-bogus "signed and unsigned" "case 15" } */
+  y < (tf?(tf<x):64); /* { dg-bogus "signed and unsigned" "case 16" } */
+
+  x > (tf?64:(tf>=x)); /* { dg-bogus "signed and unsigned" "case 17" } */
+  y > (tf?64:(tf>=x)); /* { dg-bogus "signed and unsigned" "case 18" } */
+  x > (tf?(tf>=x):64); /* { dg-bogus "signed and unsigned" "case 19" } */
+  y > (tf?(tf>=x):64); /* { dg-bogus "signed and unsigned" "case 20" } */
+
+  x > (tf?64:(tf<=x)); /* { dg-bogus "signed and unsigned" "case 21" } */
+  y > (tf?64:(tf<=x)); /* { dg-bogus "signed and unsigned" "case 22" } */
+  x > (tf?(tf<=x):64); /* { dg-bogus "signed and unsigned" "case 23" } */
+  y > (tf?(tf<=x):64); /* { dg-bogus "signed and unsigned" "case 24" } */
+
+  x > (tf?64:(tf&&x)); /* { dg-bogus "signed and unsigned" "case 25" } */
+  y > (tf?64:(tf&&x)); /* { dg-bogus "signed and unsigned" "case 26" } */
+  x > (tf?(tf&&x):64); /* { dg-bogus "signed and unsigned" "case 27" } */
+  y > (tf?(tf&&x):64); /* { dg-bogus "signed and unsigned" "case 28" } */
+
+  x > (tf?64:(tf||x)); /* { dg-bogus "signed and unsigned" "case 29" } */
+  y > (tf?64:(tf||x)); /* { dg-bogus "signed and unsigned" "case 30" } */
+  x > (tf?(tf||x):64); /* { dg-bogus "signed and unsigned" "case 31" } */
+  y > (tf?(tf||x):64); /* { dg-bogus "signed and unsigned" "case 32" } */
+
+  x > (tf?64:(!tf)); /* { dg-bogus "signed and unsigned" "case 33" } */
+  y > (tf?64:(!tf)); /* { dg-bogus "signed and unsigned" "case 34" } */
+  x > (tf?(!tf):64); /* { dg-bogus "signed and unsigned" "case 35" } */
+  y > (tf?(!tf):64); /* { dg-bogus "signed and unsigned" "case 36" } */
+
+}

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