aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorManuel López-Ibáñez <manu@gcc.gnu.org>2012-05-03 22:37:01 +0000
committerManuel López-Ibáñez <manu@gcc.gnu.org>2012-05-03 22:37:01 +0000
commit50f305cacf8dbf91656ffd5412a1b95fdc6351e2 (patch)
tree14abe4e1a206a9b970b7a19868ab17246a847071
parent0c3641b0ea030a15cc2b61bdd0d4e200086243e5 (diff)
downloadgcc-50f305cacf8dbf91656ffd5412a1b95fdc6351e2.zip
gcc-50f305cacf8dbf91656ffd5412a1b95fdc6351e2.tar.gz
gcc-50f305cacf8dbf91656ffd5412a1b95fdc6351e2.tar.bz2
re PR c/51712 (-Wtype-limits should not trigger for types of implementation-defined signedness)
2012-05-04 Manuel López-Ibáñez <manu@gcc.gnu.org> PR c/51712 c-family/ * c-common.c (expr_original_type): New. (shorten_compare): Do not warn for enumeration types. testsuite/ * c-c++-common/pr51712.c: New. From-SVN: r187125
-rw-r--r--gcc/c-family/ChangeLog6
-rw-r--r--gcc/c-family/c-common.c50
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/c-c++-common/pr51712.c18
4 files changed, 61 insertions, 18 deletions
diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog
index 05c2c75..1c805e8 100644
--- a/gcc/c-family/ChangeLog
+++ b/gcc/c-family/ChangeLog
@@ -1,3 +1,9 @@
+2012-05-04 Manuel López-Ibáñez <manu@gcc.gnu.org>
+
+ PR c/51712
+ * c-common.c (expr_original_type): New.
+ (shorten_compare): Do not warn for enumeration types.
+
2012-05-03 Manuel López-Ibáñez <manu@gcc.gnu.org>
* c.opt (fpermissive): Add Var(flag_permissive).
diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c
index dce3902..f3a6746 100644
--- a/gcc/c-family/c-common.c
+++ b/gcc/c-family/c-common.c
@@ -3481,6 +3481,15 @@ binary_op_error (location_t location, enum tree_code code,
type0, type1);
}
+/* Given an expression as a tree, return its original type. Do this
+ by stripping any conversion that preserves the sign and precision. */
+static tree
+expr_original_type (tree expr)
+{
+ STRIP_SIGN_NOPS (expr);
+ return TREE_TYPE (expr);
+}
+
/* Subroutine of build_binary_op, used for comparison operations.
See if the operands have both been converted from subword integer types
and, if so, perhaps change them both back to their original type.
@@ -3506,6 +3515,7 @@ shorten_compare (tree *op0_ptr, tree *op1_ptr, tree *restype_ptr,
int real1, real2;
tree primop0, primop1;
enum tree_code code = *rescode_ptr;
+ location_t loc = EXPR_LOC_OR_HERE (op0);
/* Throw away any conversions to wider types
already present in the operands. */
@@ -3726,9 +3736,11 @@ shorten_compare (tree *op0_ptr, tree *op1_ptr, tree *restype_ptr,
if (TREE_CODE (primop0) != INTEGER_CST)
{
if (val == truthvalue_false_node)
- warning (OPT_Wtype_limits, "comparison is always false due to limited range of data type");
+ warning_at (loc, OPT_Wtype_limits,
+ "comparison is always false due to limited range of data type");
if (val == truthvalue_true_node)
- warning (OPT_Wtype_limits, "comparison is always true due to limited range of data type");
+ warning_at (loc, OPT_Wtype_limits,
+ "comparison is always true due to limited range of data type");
}
if (val != 0)
@@ -3795,29 +3807,31 @@ shorten_compare (tree *op0_ptr, tree *op1_ptr, tree *restype_ptr,
&& TYPE_UNSIGNED (*restype_ptr))
{
tree value = 0;
+ /* All unsigned values are >= 0, so we warn. However,
+ if OP0 is a constant that is >= 0, the signedness of
+ the comparison isn't an issue, so suppress the
+ warning. */
+ bool warn =
+ warn_type_limits && !in_system_header
+ && !(TREE_CODE (primop0) == INTEGER_CST
+ && !TREE_OVERFLOW (convert (c_common_signed_type (type),
+ primop0)))
+ /* Do not warn for enumeration types. */
+ && (TREE_CODE (expr_original_type (primop0)) != ENUMERAL_TYPE);
+
switch (code)
{
case GE_EXPR:
- /* All unsigned values are >= 0, so we warn. However,
- if OP0 is a constant that is >= 0, the signedness of
- the comparison isn't an issue, so suppress the
- warning. */
- if (warn_type_limits && !in_system_header
- && !(TREE_CODE (primop0) == INTEGER_CST
- && !TREE_OVERFLOW (convert (c_common_signed_type (type),
- primop0))))
- warning (OPT_Wtype_limits,
- "comparison of unsigned expression >= 0 is always true");
+ if (warn)
+ warning_at (loc, OPT_Wtype_limits,
+ "comparison of unsigned expression >= 0 is always true");
value = truthvalue_true_node;
break;
case LT_EXPR:
- if (warn_type_limits && !in_system_header
- && !(TREE_CODE (primop0) == INTEGER_CST
- && !TREE_OVERFLOW (convert (c_common_signed_type (type),
- primop0))))
- warning (OPT_Wtype_limits,
- "comparison of unsigned expression < 0 is always false");
+ if (warn)
+ warning_at (loc, OPT_Wtype_limits,
+ "comparison of unsigned expression < 0 is always false");
value = truthvalue_false_node;
break;
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 0395dc7..4600d5c 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2012-05-04 Manuel López-Ibáñez <manu@gcc.gnu.org>
+
+ PR c/51712
+ * c-c++-common/pr51712.c: New.
+
2012-05-03 Michael Meissner <meissner@linux.vnet.ibm.com>
PR target/53199
diff --git a/gcc/testsuite/c-c++-common/pr51712.c b/gcc/testsuite/c-c++-common/pr51712.c
new file mode 100644
index 0000000..4d9eba3
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/pr51712.c
@@ -0,0 +1,18 @@
+/* PR c/51712 */
+/* { dg-do compile } */
+/* { dg-options "-Wtype-limits" } */
+
+enum test_enum {
+ FOO,
+ BAR
+};
+
+int valid(enum test_enum arg)
+{
+ return arg >= 0 && arg <= BAR;
+}
+
+int valid2(unsigned int arg2)
+{
+ return arg2 >= FOO && arg2 <= BAR; /* { dg-bogus "comparison of unsigned expression" "" { xfail *-*-* } } */
+}