re PR c++/34198 (-Wconversion gives apparent erroneous warning with g++ 4.3-20071109)
PR c++/34198 * c-common.c (conversion_warning): For INTEGER_TYPE to INTEGER_TYPE conversions call get_narrower on expr to avoid spurious warnings from binop shortening or when the implicit conversion can't change the value. * gcc.dg/Wconversion-5.c: New test. * g++.dg/Wconversion3.C: New test. From-SVN: r130377
This commit is contained in:
parent
bb1f5840b5
commit
cfdaefecf6
5 changed files with 114 additions and 5 deletions
|
@ -1,3 +1,11 @@
|
|||
2007-11-23 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR c++/34198
|
||||
* c-common.c (conversion_warning): For INTEGER_TYPE to
|
||||
INTEGER_TYPE conversions call get_narrower on expr to avoid
|
||||
spurious warnings from binop shortening or when the implicit
|
||||
conversion can't change the value.
|
||||
|
||||
2007-11-22 Joseph Myers <joseph@codesourcery.com>
|
||||
|
||||
PR c/14050
|
||||
|
|
|
@ -1280,6 +1280,14 @@ conversion_warning (tree type, tree expr)
|
|||
else if (TREE_CODE (TREE_TYPE (expr)) == INTEGER_TYPE
|
||||
&& TREE_CODE (type) == INTEGER_TYPE)
|
||||
{
|
||||
/* Don't warn about unsigned char y = 0xff, x = (int) y; */
|
||||
int uns;
|
||||
tree orig_expr = expr;
|
||||
expr = get_narrower (expr, &uns);
|
||||
|
||||
if (expr == orig_expr)
|
||||
uns = TYPE_UNSIGNED (TREE_TYPE (expr));
|
||||
|
||||
/* Warn for integer types converted to smaller integer types. */
|
||||
if (formal_prec < TYPE_PRECISION (TREE_TYPE (expr)))
|
||||
give_warning = true;
|
||||
|
@ -1287,14 +1295,31 @@ conversion_warning (tree type, tree expr)
|
|||
/* When they are the same width but different signedness,
|
||||
then the value may change. */
|
||||
else if ((formal_prec == TYPE_PRECISION (TREE_TYPE (expr))
|
||||
&& TYPE_UNSIGNED (TREE_TYPE (expr)) != TYPE_UNSIGNED (type))
|
||||
&& uns != TYPE_UNSIGNED (type))
|
||||
/* Even when converted to a bigger type, if the type is
|
||||
unsigned but expr is signed, then negative values
|
||||
will be changed. */
|
||||
|| (TYPE_UNSIGNED (type) && !TYPE_UNSIGNED (TREE_TYPE (expr))))
|
||||
warning (OPT_Wsign_conversion,
|
||||
"conversion to %qT from %qT may change the sign of the result",
|
||||
type, TREE_TYPE (expr));
|
||||
|| (TYPE_UNSIGNED (type) && !uns))
|
||||
{
|
||||
if (uns != TYPE_UNSIGNED (TREE_TYPE (expr)))
|
||||
{
|
||||
/* For signed char s1, s2 = (int) (unsigned char) s1;
|
||||
get_narrower returns s1, but uns = 1. Find the
|
||||
narrowest type with uns == TYPE_UNSIGNED (type). */
|
||||
tree unsexpr = orig_expr;
|
||||
|
||||
while (TREE_CODE (unsexpr) == NOP_EXPR
|
||||
&& unsexpr != expr
|
||||
&& TYPE_UNSIGNED (TREE_TYPE (TREE_OPERAND (unsexpr,
|
||||
0)))
|
||||
== uns)
|
||||
unsexpr = TREE_OPERAND (unsexpr, 0);
|
||||
expr = unsexpr;
|
||||
}
|
||||
warning (OPT_Wsign_conversion,
|
||||
"conversion to %qT from %qT may change the sign of the result",
|
||||
type, TREE_TYPE (expr));
|
||||
}
|
||||
}
|
||||
|
||||
/* Warn for integer types converted to real types if and only if
|
||||
|
|
|
@ -1,3 +1,9 @@
|
|||
2007-11-23 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR c++/34198
|
||||
* gcc.dg/Wconversion-5.c: New test.
|
||||
* g++.dg/Wconversion3.C: New test.
|
||||
|
||||
2007-11-23 Richard Guenther <rguenther@suse.de>
|
||||
|
||||
* gcc.dg/tree-ssa/alias-17.c: New testcase.
|
||||
|
|
35
gcc/testsuite/g++.dg/warn/Wconversion3.C
Normal file
35
gcc/testsuite/g++.dg/warn/Wconversion3.C
Normal file
|
@ -0,0 +1,35 @@
|
|||
// PR c++/34198
|
||||
// { dg-do compile }
|
||||
// { dg-options "-O2 -Wconversion -Wsign-conversion" }
|
||||
|
||||
signed char sc;
|
||||
unsigned char uc;
|
||||
short int ss;
|
||||
unsigned short int us;
|
||||
int si;
|
||||
unsigned int ui;
|
||||
|
||||
void test1 (void)
|
||||
{
|
||||
int a = uc & 0xff;
|
||||
int b = sc & 0x7f;
|
||||
int c = 0xff & uc;
|
||||
int d = 0x7f & sc;
|
||||
int e = uc & sc;
|
||||
unsigned char f = (int) uc;
|
||||
signed char g = (int) sc;
|
||||
unsigned char h = (unsigned int) (short int) uc;
|
||||
signed char i = (int) (unsigned short int) sc; // { dg-warning "may alter its value" }
|
||||
unsigned char j = (unsigned int) (short int) us; // { dg-warning "may alter its value" }
|
||||
signed char k = (int) (unsigned short int) ss; // { dg-warning "may alter its value" }
|
||||
}
|
||||
|
||||
void test2 (void)
|
||||
{
|
||||
signed char a = (unsigned char) sc; // { dg-warning "may change the sign" }
|
||||
unsigned char b = (signed char) uc; // { dg-warning "may change the sign" }
|
||||
signed char c = (int) (unsigned char) sc; // { dg-warning "may change the sign" }
|
||||
unsigned char d = (int) (signed char) uc; // { dg-warning "may change the sign" }
|
||||
int e = (unsigned int) si; // { dg-warning "may change the sign" }
|
||||
unsigned int f = (int) ui; // { dg-warning "may change the sign" }
|
||||
}
|
35
gcc/testsuite/gcc.dg/Wconversion-5.c
Normal file
35
gcc/testsuite/gcc.dg/Wconversion-5.c
Normal file
|
@ -0,0 +1,35 @@
|
|||
/* PR c++/34198 */
|
||||
/* { dg-do compile } */
|
||||
/* { dg-options "-O2 -Wconversion" } */
|
||||
|
||||
signed char sc;
|
||||
unsigned char uc;
|
||||
short int ss;
|
||||
unsigned short int us;
|
||||
int si;
|
||||
unsigned int ui;
|
||||
|
||||
void test1 (void)
|
||||
{
|
||||
int a = uc & 0xff;
|
||||
int b = sc & 0x7f;
|
||||
int c = 0xff & uc;
|
||||
int d = 0x7f & sc;
|
||||
int e = uc & sc;
|
||||
unsigned char f = (int) uc;
|
||||
signed char g = (int) sc;
|
||||
unsigned char h = (unsigned int) (short int) uc;
|
||||
signed char i = (int) (unsigned short int) sc; /* { dg-warning "may alter its value" } */
|
||||
unsigned char j = (unsigned int) (short int) us; /* { dg-warning "may alter its value" } */
|
||||
signed char k = (int) (unsigned short int) ss; /* { dg-warning "may alter its value" } */
|
||||
}
|
||||
|
||||
void test2 (void)
|
||||
{
|
||||
signed char a = (unsigned char) sc; /* { dg-warning "may change the sign" } */
|
||||
unsigned char b = (signed char) uc; /* { dg-warning "may change the sign" } */
|
||||
signed char c = (int) (unsigned char) sc; /* { dg-warning "may change the sign" } */
|
||||
unsigned char d = (int) (signed char) uc; /* { dg-warning "may change the sign" } */
|
||||
int e = (unsigned int) si; /* { dg-warning "may change the sign" } */
|
||||
unsigned int f = (int) ui; /* { dg-warning "may change the sign" } */
|
||||
}
|
Loading…
Add table
Reference in a new issue