aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIan Lance Taylor <iant@google.com>2009-06-25 19:20:59 +0000
committerIan Lance Taylor <ian@gcc.gnu.org>2009-06-25 19:20:59 +0000
commit82a71a267ee8a794b34612b666ea989095485f6d (patch)
treed822664648292cfa79d34a59498d4e65fcfefcac
parent96be7a11070fd121d25f14c8fcc206c98ed63942 (diff)
downloadgcc-82a71a267ee8a794b34612b666ea989095485f6d.zip
gcc-82a71a267ee8a794b34612b666ea989095485f6d.tar.gz
gcc-82a71a267ee8a794b34612b666ea989095485f6d.tar.bz2
call.c (avoid_sign_compare_warnings): New static function.
cp/: * call.c (avoid_sign_compare_warnings): New static function. (build_new_op): Call it. * typeck.c (cp_build_binary_op): Don't call warn_sign_compare if TREE_NO_WARNING is set on either operand. testsuite/: * g++.dg/warn/Wsign-compare-3.C: New testcase. From-SVN: r148952
-rw-r--r--gcc/cp/ChangeLog7
-rw-r--r--gcc/cp/call.c26
-rw-r--r--gcc/cp/typeck.c2
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/g++.dg/warn/Wsign-compare-3.C13
5 files changed, 52 insertions, 0 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index dcb35e6..7507deb 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,5 +1,12 @@
2009-06-25 Ian Lance Taylor <iant@google.com>
+ * call.c (avoid_sign_compare_warnings): New static function.
+ (build_new_op): Call it.
+ * typeck.c (cp_build_binary_op): Don't call warn_sign_compare if
+ TREE_NO_WARNING is set on either operand.
+
+2009-06-25 Ian Lance Taylor <iant@google.com>
+
* g++spec.c (SKIPOPT): define.
(lang_specific_driver): Handle -static-libstdc++. Only add
LIBSTDCXX_STATIC if we add LIBSTDCXX.
diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index e89d585..f0d624e 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -4045,10 +4045,32 @@ add_candidates (tree fns, 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;
+}
+
tree
build_new_op (enum tree_code code, int flags, tree arg1, tree arg2, tree arg3,
bool *overloaded_p, 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;
@@ -4350,6 +4372,10 @@ build_new_op (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 0799db3..e502021 100644
--- a/gcc/cp/typeck.c
+++ b/gcc/cp/typeck.c
@@ -4018,6 +4018,8 @@ 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
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index bf0fd4a..172746f 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,5 +1,9 @@
2009-06-25 Ian Lance Taylor <iant@google.com>
+ * g++.dg/warn/Wsign-compare-3.C: New testcase.
+
+2009-06-25 Ian Lance Taylor <iant@google.com>
+
* g++.dg/warn/Wunused-16.C: New testcase.
2009-06-25 Ian Lance Taylor <iant@google.com>
diff --git a/gcc/testsuite/g++.dg/warn/Wsign-compare-3.C b/gcc/testsuite/g++.dg/warn/Wsign-compare-3.C
new file mode 100644
index 0000000..dc42f41
--- /dev/null
+++ b/gcc/testsuite/g++.dg/warn/Wsign-compare-3.C
@@ -0,0 +1,13 @@
+// { dg-do compile }
+// { dg-options "-Wsign-compare" }
+
+enum E { A, B, C };
+extern void f1(int);
+void
+f2(E v1, E v2)
+{
+ for (unsigned int i = v1; i <= v2; ++i)
+ f1(i);
+ for (int i = v1; i <= v2; ++i)
+ f1(i);
+}