On Thu, Apr 30, 2015 at 11:42:18AM +0200, Andreas Schwab wrote:
> Marek Polacek <[email protected]> writes:
>
> > PR c/64610
> > * c-common.c (maybe_warn_bool_compare): Warn when comparing a boolean
> > with 0/1.
>
> /usr/local/gcc/gcc-20150430/Build/./prev-gcc/xg++
> -B/usr/local/gcc/gcc-20150430/Build/./prev-gcc/
> -B/usr/aarch64-suse-linux/bin/ -nostdinc++
> -B/usr/local/gcc/gcc-20150430/Build/prev-aarch64-suse-linux/libstdc++-v3/src/.libs
>
> -B/usr/local/gcc/gcc-20150430/Build/prev-aarch64-suse-linux/libstdc++-v3/libsupc++/.libs
>
> -I/usr/local/gcc/gcc-20150430/Build/prev-aarch64-suse-linux/libstdc++-v3/include/aarch64-suse-linux
>
> -I/usr/local/gcc/gcc-20150430/Build/prev-aarch64-suse-linux/libstdc++-v3/include
> -I/usr/local/gcc/gcc-20150430/libstdc++-v3/libsupc++
> -L/usr/local/gcc/gcc-20150430/Build/prev-aarch64-suse-linux/libstdc++-v3/src/.libs
>
> -L/usr/local/gcc/gcc-20150430/Build/prev-aarch64-suse-linux/libstdc++-v3/libsupc++/.libs
> -c -g -O2 -gtoggle -DIN_GCC -fno-exceptions -fno-rtti
> -fasynchronous-unwind-tables -W -Wall -Wno-narrowing -Wwrite-strings
> -Wcast-qual -Wmissing-format-attribute -Woverloaded-virtual -pedantic
> -Wno-long-long -Wno-variadic-macros -Wno-overlength-strings -Werror
> -fno-common -DHAVE_CONFIG_H -I. -I. -I../../gcc -I../../gcc/.
> -I../../gcc/../include -I../../gcc/../libcpp/include
> -I../../gcc/../libdecnumber -I../../gcc/../libdecnumber/dpd -I../libdecnumber
> -I../../gcc/../libbacktrace -o expr.o -MT expr.o -MMD -MP -MF
> ./.deps/expr.TPo ../../gcc/expr.c
> ../../gcc/expr.c: In function 'int can_store_by_pieces(long unsigned int,
> rtx_def* (*)(void*, long int, machine_mode), void*, unsigned int, bool)':
> ../../gcc/expr.c:2496:16: error: comparison of constant 'true' with boolean
> expression is always true [-Werror=bool-compare]
> reverse <= (HAVE_PRE_DECREMENT || HAVE_POST_DECREMENT);
> ^
Yes, that is a bug in my code; I think I'll apply the following after
regtest/bootstrap (with a proper test). If you could perhaps try the
patch as well, it'd be appreciated.
diff --git gcc/c-family/c-common.c gcc/c-family/c-common.c
index 7d314f8..ada8e8a 100644
--- gcc/c-family/c-common.c
+++ gcc/c-family/c-common.c
@@ -11924,6 +11924,17 @@ maybe_warn_bool_compare (location_t loc, enum
tree_code code, tree op0,
}
else if (integer_zerop (cst) || integer_onep (cst))
{
+ /* If the non-constant operand isn't of a boolean type, we
+ don't want to warn here. */
+ tree noncst = TREE_CODE (op0) == INTEGER_CST ? op1 : op0;
+ /* Handle booleans promoted to integers. */
+ if (CONVERT_EXPR_P (noncst)
+ && TREE_TYPE (noncst) == integer_type_node
+ && TREE_CODE (TREE_TYPE (TREE_OPERAND (noncst, 0))) == BOOLEAN_TYPE)
+ /* Warn. */;
+ else if (TREE_CODE (TREE_TYPE (noncst)) != BOOLEAN_TYPE
+ && !truth_value_p (TREE_CODE (noncst)))
+ return;
/* Do some magic to get the right diagnostics. */
bool flag = TREE_CODE (op0) == INTEGER_CST;
flag = integer_zerop (cst) ? flag : !flag;
Marek