OSDN Git Service

cp/:
authorian <ian@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 25 Jun 2009 19:20:59 +0000 (19:20 +0000)
committerian <ian@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 25 Jun 2009 19:20:59 +0000 (19:20 +0000)
* 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.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@148952 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/cp/ChangeLog
gcc/cp/call.c
gcc/cp/typeck.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/warn/Wsign-compare-3.C [new file with mode: 0644]

index dcb35e6..7507deb 100644 (file)
@@ -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.
index e89d585..f0d624e 100644 (file)
@@ -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:
index 0799db3..e502021 100644 (file)
@@ -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
index bf0fd4a..172746f 100644 (file)
@@ -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 (file)
index 0000000..dc42f41
--- /dev/null
@@ -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);
+}