aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog5
-rw-r--r--gcc/c-family/ChangeLog5
-rw-r--r--gcc/c-family/c.opt4
-rw-r--r--gcc/c/ChangeLog6
-rw-r--r--gcc/c/c-typeck.c26
-rw-r--r--gcc/cp/ChangeLog6
-rw-r--r--gcc/cp/typeck.c10
-rw-r--r--gcc/doc/invoke.texi16
-rw-r--r--gcc/testsuite/ChangeLog8
-rw-r--r--gcc/testsuite/c-c++-common/Wbool-operation-1.c36
-rw-r--r--gcc/testsuite/gcc.dg/Wbool-operation-1.c16
11 files changed, 134 insertions, 4 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 316bfaf..0059dd4 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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,
diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog
index 3dfb39f..8bcbd06 100644
--- a/gcc/c-family/ChangeLog
+++ b/gcc/c-family/ChangeLog
@@ -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
diff --git a/gcc/c-family/c.opt b/gcc/c-family/c.opt
index a04618d..4a9b9e8 100644
--- a/gcc/c-family/c.opt
+++ b/gcc/c-family/c.opt
@@ -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.
diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog
index 283cfda..cae5c92 100644
--- a/gcc/c/ChangeLog
+++ b/gcc/c/ChangeLog
@@ -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
diff --git a/gcc/c/c-typeck.c b/gcc/c/c-typeck.c
index 059ad1f..e5c7256 100644
--- a/gcc/c/c-typeck.c
+++ b/gcc/c/c-typeck.c
@@ -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);
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index a3430bf..cd5f936 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -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
diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c
index b2af615..0142d4a 100644
--- a/gcc/cp/typeck.c
+++ b/gcc/cp/typeck.c
@@ -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:
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index e6f503f..a5481b5 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -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
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index f387022..77ef74b 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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.
diff --git a/gcc/testsuite/c-c++-common/Wbool-operation-1.c b/gcc/testsuite/c-c++-common/Wbool-operation-1.c
new file mode 100644
index 0000000..bb72784
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/Wbool-operation-1.c
@@ -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;
+}
diff --git a/gcc/testsuite/gcc.dg/Wbool-operation-1.c b/gcc/testsuite/gcc.dg/Wbool-operation-1.c
new file mode 100644
index 0000000..b24e763
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Wbool-operation-1.c
@@ -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;
+}