+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.
}
}
+/* 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;
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:
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
+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.