diff options
author | Manuel López-Ibáñez <manu@gcc.gnu.org> | 2012-05-03 22:37:01 +0000 |
---|---|---|
committer | Manuel López-Ibáñez <manu@gcc.gnu.org> | 2012-05-03 22:37:01 +0000 |
commit | 50f305cacf8dbf91656ffd5412a1b95fdc6351e2 (patch) | |
tree | 14abe4e1a206a9b970b7a19868ab17246a847071 /gcc | |
parent | 0c3641b0ea030a15cc2b61bdd0d4e200086243e5 (diff) | |
download | gcc-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
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/c-family/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/c-family/c-common.c | 50 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/c-c++-common/pr51712.c | 18 |
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 *-*-* } } */ +} |