This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Patch: silence bogus sign-compare warnings on truth values in ?:
- To: gcc-patches at gcc dot gnu dot org
- Subject: Patch: silence bogus sign-compare warnings on truth values in ?:
- From: "Kaveh R. Ghazi" <ghazi at caip dot rutgers dot edu>
- Date: Sun, 17 Dec 2000 20:05:33 -0500 (EST)
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" } */
+
+}