From 50f305cacf8dbf91656ffd5412a1b95fdc6351e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20L=C3=B3pez-Ib=C3=A1=C3=B1ez?= Date: Thu, 3 May 2012 22:37:01 +0000 Subject: [PATCH] re PR c/51712 (-Wtype-limits should not trigger for types of implementation-defined signedness) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 2012-05-04 Manuel López-Ibáñez 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 --- gcc/c-family/ChangeLog | 6 ++++ gcc/c-family/c-common.c | 50 ++++++++++++++++++---------- gcc/testsuite/ChangeLog | 5 +++ gcc/testsuite/c-c++-common/pr51712.c | 18 ++++++++++ 4 files changed, 61 insertions(+), 18 deletions(-) create mode 100644 gcc/testsuite/c-c++-common/pr51712.c diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog index 05c2c7549835..1c805e8694ba 100644 --- a/gcc/c-family/ChangeLog +++ b/gcc/c-family/ChangeLog @@ -1,3 +1,9 @@ +2012-05-04 Manuel López-Ibáñez + + 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 * c.opt (fpermissive): Add Var(flag_permissive). diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c index dce390260cda..f3a6746d7c9f 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 0395dc725394..4600d5cb8834 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2012-05-04 Manuel López-Ibáñez + + PR c/51712 + * c-c++-common/pr51712.c: New. + 2012-05-03 Michael Meissner 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 000000000000..4d9eba33afef --- /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 *-*-* } } */ +}