aboutsummaryrefslogtreecommitdiff
path: root/gcc/c
diff options
context:
space:
mode:
authorMarek Polacek <polacek@redhat.com>2016-09-24 09:39:23 +0000
committerMarek Polacek <mpolacek@gcc.gnu.org>2016-09-24 09:39:23 +0000
commit9a2300e956daf1dd27e144d19ef95988ac661274 (patch)
tree2202f7c8afd097fcf4c53d3a4cbe532ead2f1c43 /gcc/c
parent02ae505bc9f8040cddaf48faaaea3bc224260853 (diff)
downloadgcc-9a2300e956daf1dd27e144d19ef95988ac661274.zip
gcc-9a2300e956daf1dd27e144d19ef95988ac661274.tar.gz
gcc-9a2300e956daf1dd27e144d19ef95988ac661274.tar.bz2
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
Diffstat (limited to 'gcc/c')
-rw-r--r--gcc/c/ChangeLog6
-rw-r--r--gcc/c/c-typeck.c26
2 files changed, 32 insertions, 0 deletions
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);