re PR c/77490 (bit-not (~) on boolean should be warned about)

PR c/77490
	* c.opt (Wbool-operation): New.

	* c-typeck.c (build_unary_op): Warn about bit not on expressions that
	have boolean value.  Warn about ++/-- on booleans.

	* typeck.c (cp_build_unary_op): Warn about bit not on expressions that
	have boolean value.

	* doc/invoke.texi: Document -Wbool-operation.

	* c-c++-common/Wbool-operation-1.c: New test.
	* gcc.dg/Wbool-operation-1.c: New test.

From-SVN: r240462
This commit is contained in:
Marek Polacek 2016-09-24 09:39:23 +00:00 committed by Marek Polacek
parent 02ae505bc9
commit 9a2300e956
11 changed files with 134 additions and 4 deletions

View File

@ -1,3 +1,8 @@
2016-09-24 Marek Polacek <polacek@redhat.com>
PR c/77490
* doc/invoke.texi: Document -Wbool-operation.
2016-09-23 Jakub Jelinek <jakub@redhat.com>
* hooks.c (hook_bool_bool_false, hook_bool_bool_gcc_optionsp_false,

View File

@ -1,3 +1,8 @@
2016-09-24 Marek Polacek <polacek@redhat.com>
PR c/77490
* c.opt (Wbool-operation): New.
2016-09-21 Bernd Edlinger <bernd.edlinger@hotmail.de>
* c-common.c (c_common_truthvalue_conversion): Inhibit

View File

@ -315,6 +315,10 @@ Wbool-compare
C ObjC C++ ObjC++ Var(warn_bool_compare) Warning LangEnabledBy(C ObjC C++ ObjC++,Wall)
Warn about boolean expression compared with an integer value different from true/false.
Wbool-operation
C ObjC C++ ObjC++ Var(warn_bool_op) Warning LangEnabledBy(C ObjC C++ ObjC++,Wall)
Warn about certain operations on boolean expressions.
Wframe-address
C ObjC C++ ObjC++ Var(warn_frame_address) Warning LangEnabledBy(C ObjC C++ ObjC++,Wall)
Warn when __builtin_frame_address or __builtin_return_address is used unsafely.

View File

@ -1,3 +1,9 @@
2016-09-24 Marek Polacek <polacek@redhat.com>
PR c/77490
* c-typeck.c (build_unary_op): Warn about bit not on expressions that
have boolean value. Warn about ++/-- on booleans.
2016-09-23 Jakub Jelinek <jakub@redhat.com>
* c-parser.c (incomplete_record_decls): Remove unnecessary

View File

@ -4196,6 +4196,22 @@ build_unary_op (location_t location, enum tree_code code, tree xarg,
|| (typecode == VECTOR_TYPE
&& !VECTOR_FLOAT_TYPE_P (TREE_TYPE (arg))))
{
tree e = arg;
/* Warn if the expression has boolean value. */
while (TREE_CODE (e) == COMPOUND_EXPR)
e = TREE_OPERAND (e, 1);
if ((TREE_CODE (TREE_TYPE (arg)) == BOOLEAN_TYPE
|| truth_value_p (TREE_CODE (e)))
&& warning_at (location, OPT_Wbool_operation,
"%<~%> on a boolean expression"))
{
gcc_rich_location richloc (location);
richloc.add_fixit_insert_before (location, "!");
inform_at_rich_loc (&richloc, "did you mean to use logical "
"not?");
}
if (!noconvert)
arg = default_conversion (arg);
}
@ -4306,6 +4322,16 @@ build_unary_op (location_t location, enum tree_code code, tree xarg,
"decrement of enumeration value is invalid in C++");
}
if (TREE_CODE (TREE_TYPE (arg)) == BOOLEAN_TYPE)
{
if (code == PREINCREMENT_EXPR || code == POSTINCREMENT_EXPR)
warning_at (location, OPT_Wbool_operation,
"increment of a boolean expression");
else
warning_at (location, OPT_Wbool_operation,
"decrement of a boolean expression");
}
/* Ensure the argument is fully folded inside any SAVE_EXPR. */
arg = c_fully_fold (arg, false, NULL);

View File

@ -1,3 +1,9 @@
2016-09-24 Marek Polacek <polacek@redhat.com>
PR c/77490
* typeck.c (cp_build_unary_op): Warn about bit not on expressions that
have boolean value.
2016-09-23 Jakub Jelinek <jakub@redhat.com>
Implement P0138R2, C++17 construction rules for enum class values

View File

@ -5792,6 +5792,7 @@ cp_build_unary_op (enum tree_code code, tree xarg, bool noconvert,
{
/* No default_conversion here. It causes trouble for ADDR_EXPR. */
tree arg = xarg;
location_t location = EXPR_LOC_OR_LOC (arg, input_location);
tree argtype = 0;
const char *errstring = NULL;
tree val;
@ -5853,7 +5854,14 @@ cp_build_unary_op (enum tree_code code, tree xarg, bool noconvert,
arg, true)))
errstring = _("wrong type argument to bit-complement");
else if (!noconvert && CP_INTEGRAL_TYPE_P (TREE_TYPE (arg)))
arg = cp_perform_integral_promotions (arg, complain);
{
/* Warn if the expression has boolean value. */
if (TREE_CODE (TREE_TYPE (arg)) == BOOLEAN_TYPE
&& warning_at (location, OPT_Wbool_operation,
"%<~%> on an expression of type bool"))
inform (location, "did you mean to use logical not (%<!%>)?");
arg = cp_perform_integral_promotions (arg, complain);
}
break;
case ABS_EXPR:

View File

@ -256,8 +256,8 @@ Objective-C and Objective-C++ Dialects}.
-pedantic-errors @gol
-w -Wextra -Wall -Waddress -Waggregate-return @gol
-Wno-aggressive-loop-optimizations -Warray-bounds -Warray-bounds=@var{n} @gol
-Wno-attributes -Wbool-compare -Wno-builtin-macro-redefined @gol
-Wc90-c99-compat -Wc99-c11-compat @gol
-Wno-attributes -Wbool-compare -Wbool-operation @gol
-Wno-builtin-macro-redefined -Wc90-c99-compat -Wc99-c11-compat @gol
-Wc++-compat -Wc++11-compat -Wc++14-compat -Wcast-align -Wcast-qual @gol
-Wchar-subscripts -Wclobbered -Wcomment -Wconditionally-supported @gol
-Wconversion -Wcoverage-mismatch -Wno-cpp -Wdangling-else -Wdate-time @gol
@ -3656,6 +3656,7 @@ Options} and @ref{Objective-C and Objective-C++ Dialect Options}.
@gccoptlist{-Waddress @gol
-Warray-bounds=1 @r{(only with} @option{-O2}@r{)} @gol
-Wbool-compare @gol
-Wbool-operation @gol
-Wc++11-compat -Wc++14-compat@gol
-Wchar-subscripts @gol
-Wcomment @gol
@ -4846,6 +4847,17 @@ if ((n > 1) == 2) @{ @dots{} @}
@end smallexample
This warning is enabled by @option{-Wall}.
@item -Wbool-operation
@opindex Wno-bool-operation
@opindex Wbool-operation
Warn about suspicious operations on expressions of a boolean type. For
instance, bitwise negation of a boolean is very likely a bug in the program.
For C, this warning also warns about incrementing or decrementing a boolean,
which rarely makes sense. (In C++, decrementing a boolean is always invalid.
Incrementing a boolean is invalid in C++1z, and deprecated otherwise.)
This warning is enabled by @option{-Wall}.
@item -Wduplicated-cond
@opindex Wno-duplicated-cond
@opindex Wduplicated-cond

View File

@ -1,3 +1,9 @@
2016-09-24 Marek Polacek <polacek@redhat.com>
PR c/77490
* c-c++-common/Wbool-operation-1.c: New test.
* gcc.dg/Wbool-operation-1.c: New test.
2016-09-23 Fritz Reese <fritzoreese@gmail.com>
* gfortran.dg/dec_static_1.f90: New.
@ -10,7 +16,7 @@
PR fortran/48298
* gfortran.dg/negative_unit_check.f90: Update test.
* gfortran.dg/dtio_14.f90: New test.
2016-09-23 Dominik Vogt <vogt@linux.vnet.ibm.com>
* gcc.target/s390/hotpatch-compile-1.c: Fixed dg-error test.

View File

@ -0,0 +1,36 @@
/* PR c/77490 */
/* { dg-do compile } */
/* { dg-options "-Wall" } */
#ifndef __cplusplus
# define bool _Bool
#endif
typedef volatile bool T;
typedef int __attribute__ ((vector_size (4 * sizeof (int)))) v4si;
extern bool foo (void);
int
fn (bool b, bool b2, T b3, int n, v4si v)
{
int r = 0;
r += ~b; /* { dg-warning "on an expression of type bool|on a boolean expression" } */
r += n + ~b; /* { dg-warning "on an expression of type bool|on a boolean expression" } */
r += ~(n == 1); /* { dg-warning "on an expression of type bool|on a boolean expression" } */
r += ~(n || 1); /* { dg-warning "on an expression of type bool|on a boolean expression" } */
r += ~b == 1; /* { dg-warning "on an expression of type bool|on a boolean expression" } */
r += ~(++n, n == 1); /* { dg-warning "on an expression of type bool|on a boolean expression" } */
r += ~(++n, n > 1); /* { dg-warning "on an expression of type bool|on a boolean expression" } */
r += ~(++n, n && 1); /* { dg-warning "on an expression of type bool|on a boolean expression" } */
r += (++n, ~b); /* { dg-warning "on an expression of type bool|on a boolean expression" } */
r += ~b3; /* { dg-warning "on an expression of type bool|on a boolean expression" } */
r += ~foo (); /* { dg-warning "on an expression of type bool|on a boolean expression" } */
r += ~(bool) !1; /* { dg-warning "on an expression of type bool|on a boolean expression" } */
v = ~v;
r += ~(int) b;
r += -b;
return r;
}

View File

@ -0,0 +1,16 @@
/* PR c/77490 */
/* { dg-do compile } */
/* { dg-options "-Wall" } */
int
fn (_Bool b)
{
int r = 0;
r += b++; /* { dg-warning "increment of a boolean expression" } */
r += ++b; /* { dg-warning "increment of a boolean expression" } */
r += b--; /* { dg-warning "decrement of a boolean expression" } */
r += --b; /* { dg-warning "decrement of a boolean expression" } */
return r;
}