summaryrefslogtreecommitdiff
path: root/gcc/c
diff options
context:
space:
mode:
authormpolacek <mpolacek@138bc75d-0d04-0410-961f-82ee72b054a4>2016-09-24 09:39:23 +0000
committermpolacek <mpolacek@138bc75d-0d04-0410-961f-82ee72b054a4>2016-09-24 09:39:23 +0000
commit481ce48135cce519b0a63fa3ea03426513a5dc44 (patch)
tree2202f7c8afd097fcf4c53d3a4cbe532ead2f1c43 /gcc/c
parent733ced655ee3fd2d1bcafdd012c650b11dc2a97e (diff)
downloadgcc-481ce48135cce519b0a63fa3ea03426513a5dc44.tar.gz
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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@240462 138bc75d-0d04-0410-961f-82ee72b054a4
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 283cfdacc2f..cae5c922067 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 059ad1fc2e0..e5c72560397 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);