aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIan Lance Taylor <iant@google.com>2012-01-14 00:22:14 +0000
committerIan Lance Taylor <ian@gcc.gnu.org>2012-01-14 00:22:14 +0000
commit12448f77a57be1954b4f15455b06de9012e88390 (patch)
tree65cee32b0b18592f5aa5a416fb63c7ceeca865bc
parent738134ef335a67def3b324823e24d2932d1baf06 (diff)
downloadgcc-12448f77a57be1954b4f15455b06de9012e88390.zip
gcc-12448f77a57be1954b4f15455b06de9012e88390.tar.gz
gcc-12448f77a57be1954b4f15455b06de9012e88390.tar.bz2
re PR c++/50012 (C++ front end misses -Wsign-compare warnings when extraneous parentheses are present)
gcc/: PR c++/50012 * tree.h (TYPE_QUALS): Add cast to int. (TYPE_QUALS_NO_ADDR_SPACE): Likewise. gcc/cp: PR c++/50012 * typeck.c (enum_cast_to_int): New static function. (cp_build_binary_op): When handling warn_sign_compare, don't test for TREE_NO_WARNING. Do call enum_cast_to_int. * call.c (avoid_sign_compare_warnings): Remove static function. (build_new_op_1): Don't call avoid_sign_compare_warnings. gcc/testsuite/: PR c++/50012 * g++.dg/warn/Wsign-compare-4.C: New. From-SVN: r183178
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/cp/ChangeLog9
-rw-r--r--gcc/cp/call.c28
-rw-r--r--gcc/cp/typeck.c35
-rw-r--r--gcc/testsuite/ChangeLog7
-rw-r--r--gcc/testsuite/g++.dg/warn/Wsign-compare-4.C12
-rw-r--r--gcc/tree.h16
7 files changed, 72 insertions, 41 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 05ad7ab..8d50926 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,11 @@
2012-01-13 Ian Lance Taylor <iant@google.com>
+ PR c++/50012
+ * tree.h (TYPE_QUALS): Add cast to int.
+ (TYPE_QUALS_NO_ADDR_SPACE): Likewise.
+
+2012-01-13 Ian Lance Taylor <iant@google.com>
+
* ipa-cp.c (ipa_get_indirect_edge_target): Add typecasts when
comparing param_index to VEC_length result.
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 051649e..86ab82f 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,12 @@
+2012-01-13 Ian Lance Taylor <iant@google.com>
+
+ PR c++/50012
+ * typeck.c (enum_cast_to_int): New static function.
+ (cp_build_binary_op): When handling warn_sign_compare, don't test
+ for TREE_NO_WARNING. Do call enum_cast_to_int.
+ * call.c (avoid_sign_compare_warnings): Remove static function.
+ (build_new_op_1): Don't call avoid_sign_compare_warnings.
+
2012-01-13 Steven Bosscher <steven@gcc.gnu.org>
* decl2.c: Do not include tree-mudflap.h
diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index f7cfbd0..aa70749 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -1,7 +1,7 @@
/* Functions related to invoking methods and overloaded functions.
Copyright (C) 1987, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009,
- 2010, 2011
+ 2010, 2011, 2012
Free Software Foundation, Inc.
Contributed by Michael Tiemann (tiemann@cygnus.com) and
modified by Brendan Kehoe (brendan@cygnus.com).
@@ -4880,32 +4880,10 @@ add_candidates (tree fns, tree first_arg, const VEC(tree,gc) *args,
}
}
-/* Even unsigned enum types promote to signed int. We don't want to
- issue -Wsign-compare warnings for this case. Here ORIG_ARG is the
- original argument and ARG is the argument after any conversions
- have been applied. We set TREE_NO_WARNING if we have added a cast
- from an unsigned enum type to a signed integer type. */
-
-static void
-avoid_sign_compare_warnings (tree orig_arg, tree arg)
-{
- if (orig_arg != NULL_TREE
- && arg != NULL_TREE
- && orig_arg != arg
- && TREE_CODE (TREE_TYPE (orig_arg)) == ENUMERAL_TYPE
- && TYPE_UNSIGNED (TREE_TYPE (orig_arg))
- && INTEGRAL_TYPE_P (TREE_TYPE (arg))
- && !TYPE_UNSIGNED (TREE_TYPE (arg)))
- TREE_NO_WARNING (arg) = 1;
-}
-
static tree
build_new_op_1 (enum tree_code code, int flags, tree arg1, tree arg2, tree arg3,
tree *overload, tsubst_flags_t complain)
{
- tree orig_arg1 = arg1;
- tree orig_arg2 = arg2;
- tree orig_arg3 = arg3;
struct z_candidate *candidates = 0, *cand;
VEC(tree,gc) *arglist;
tree fnname;
@@ -5200,10 +5178,6 @@ build_new_op_1 (enum tree_code code, int flags, tree arg1, tree arg2, tree arg3,
return result;
builtin:
- avoid_sign_compare_warnings (orig_arg1, arg1);
- avoid_sign_compare_warnings (orig_arg2, arg2);
- avoid_sign_compare_warnings (orig_arg3, arg3);
-
switch (code)
{
case MODIFY_EXPR:
diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c
index d9166c9..11edeee 100644
--- a/gcc/cp/typeck.c
+++ b/gcc/cp/typeck.c
@@ -1,6 +1,7 @@
/* Build expressions with type checking for C++ compiler.
Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
- 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
+ 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
+ 2011, 2012
Free Software Foundation, Inc.
Hacked by Michael Tiemann (tiemann@cygnus.com)
@@ -3599,6 +3600,29 @@ build_x_array_ref (tree arg1, tree arg2, tsubst_flags_t complain)
return expr;
}
+/* Return whether OP is an expression of enum type cast to integer
+ type. In C++ even unsigned enum types are cast to signed integer
+ types. We do not want to issue warnings about comparisons between
+ signed and unsigned types when one of the types is an enum type.
+ Those warnings are always false positives in practice. */
+
+static bool
+enum_cast_to_int (tree op)
+{
+ if (TREE_CODE (op) == NOP_EXPR
+ && TREE_TYPE (op) == integer_type_node
+ && TREE_CODE (TREE_TYPE (TREE_OPERAND (op, 0))) == ENUMERAL_TYPE
+ && TYPE_UNSIGNED (TREE_TYPE (TREE_OPERAND (op, 0))))
+ return true;
+
+ /* The cast may have been pushed into a COND_EXPR. */
+ if (TREE_CODE (op) == COND_EXPR)
+ return (enum_cast_to_int (TREE_OPERAND (op, 1))
+ || enum_cast_to_int (TREE_OPERAND (op, 2)));
+
+ return false;
+}
+
/* For the c-common bits. */
tree
build_binary_op (location_t location, enum tree_code code, tree op0, tree op1,
@@ -4465,13 +4489,15 @@ cp_build_binary_op (location_t location,
if ((short_compare || code == MIN_EXPR || code == MAX_EXPR)
&& warn_sign_compare
- && !TREE_NO_WARNING (orig_op0)
- && !TREE_NO_WARNING (orig_op1)
/* Do not warn until the template is instantiated; we cannot
bound the ranges of the arguments until that point. */
&& !processing_template_decl
&& (complain & tf_warning)
- && c_inhibit_evaluation_warnings == 0)
+ && c_inhibit_evaluation_warnings == 0
+ /* Even unsigned enum types promote to signed int. We don't
+ want to issue -Wsign-compare warnings for this case. */
+ && !enum_cast_to_int (orig_op0)
+ && !enum_cast_to_int (orig_op1))
{
warn_for_sign_compare (location, orig_op0, orig_op1, op0, op1,
result_type, resultcode);
@@ -8525,4 +8551,3 @@ check_literal_operator_args (const_tree decl,
return true;
}
}
-
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 44cf019..e47c3b2 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2012-01-13 Ian Lance Taylor <iant@google.com>
+
+ PR c++/50012
+ * g++.dg/warn/Wsign-compare-4.C: New.
+
2012-01-13 Paul Thomas <pault@gcc.gnu.org>
PR fortran/48351
@@ -21,7 +26,7 @@
int32plus because of big array needed.
* gcc.dg/pr50527.c: Don't FAIL if sizeof(void*) = 2
* gcc.dg/lto/20090218-2_1.c: Fix prototype of malloc, memcpy.
-
+
2012-01-13 Jason Merrill <jason@redhat.com>
PR c++/51813
diff --git a/gcc/testsuite/g++.dg/warn/Wsign-compare-4.C b/gcc/testsuite/g++.dg/warn/Wsign-compare-4.C
new file mode 100644
index 0000000..b3eb8e2
--- /dev/null
+++ b/gcc/testsuite/g++.dg/warn/Wsign-compare-4.C
@@ -0,0 +1,12 @@
+//PR c++/50012
+// { dg-options "-Wsign-compare" }
+
+int foo(unsigned int *a, int b)
+{
+ return (*a) <= b; // { dg-warning "comparison between signed and unsigned" }
+}
+
+int bar(unsigned int *a, int b)
+{
+ return *a <= b; // { dg-warning "comparison between signed and unsigned" }
+}
diff --git a/gcc/tree.h b/gcc/tree.h
index 3f9fdbc..5719b8f 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -1,6 +1,6 @@
/* Front-end tree definitions for GNU compiler.
Copyright (C) 1989, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
- 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
+ 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012
Free Software Foundation, Inc.
This file is part of GCC.
@@ -2298,16 +2298,16 @@ enum cv_qualifier
/* The set of type qualifiers for this type. */
#define TYPE_QUALS(NODE) \
- ((TYPE_READONLY (NODE) * TYPE_QUAL_CONST) \
- | (TYPE_VOLATILE (NODE) * TYPE_QUAL_VOLATILE) \
- | (TYPE_RESTRICT (NODE) * TYPE_QUAL_RESTRICT) \
- | (ENCODE_QUAL_ADDR_SPACE (TYPE_ADDR_SPACE (NODE))))
+ ((int) ((TYPE_READONLY (NODE) * TYPE_QUAL_CONST) \
+ | (TYPE_VOLATILE (NODE) * TYPE_QUAL_VOLATILE) \
+ | (TYPE_RESTRICT (NODE) * TYPE_QUAL_RESTRICT) \
+ | (ENCODE_QUAL_ADDR_SPACE (TYPE_ADDR_SPACE (NODE)))))
/* The same as TYPE_QUALS without the address space qualifications. */
#define TYPE_QUALS_NO_ADDR_SPACE(NODE) \
- ((TYPE_READONLY (NODE) * TYPE_QUAL_CONST) \
- | (TYPE_VOLATILE (NODE) * TYPE_QUAL_VOLATILE) \
- | (TYPE_RESTRICT (NODE) * TYPE_QUAL_RESTRICT))
+ ((int) ((TYPE_READONLY (NODE) * TYPE_QUAL_CONST) \
+ | (TYPE_VOLATILE (NODE) * TYPE_QUAL_VOLATILE) \
+ | (TYPE_RESTRICT (NODE) * TYPE_QUAL_RESTRICT)))
/* These flags are available for each language front end to use internally. */
#define TYPE_LANG_FLAG_0(NODE) (TYPE_CHECK (NODE)->type_common.lang_flag_0)