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
This commit is contained in:
Ian Lance Taylor 2009-06-25 19:20:59 +00:00 committed by Ian Lance Taylor
parent 96be7a1107
commit 82a71a267e
5 changed files with 52 additions and 0 deletions

View File

@ -1,3 +1,10 @@
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.

View 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:

View 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

View File

@ -1,3 +1,7 @@
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.

View File

@ -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);
}