diff options
author | Manuel López-Ibáñez <manu@gcc.gnu.org> | 2008-08-20 16:09:45 +0000 |
---|---|---|
committer | Manuel López-Ibáñez <manu@gcc.gnu.org> | 2008-08-20 16:09:45 +0000 |
commit | 9c591bd0849e4ed59a584aeced67053944f13b0b (patch) | |
tree | e4b280fa4d233f4a7258a47cdc899fe8254038f0 | |
parent | 0011dedbd9dbfa01b2f4d3390ef3ed2d6ea1dd6d (diff) | |
download | gcc-9c591bd0849e4ed59a584aeced67053944f13b0b.zip gcc-9c591bd0849e4ed59a584aeced67053944f13b0b.tar.gz gcc-9c591bd0849e4ed59a584aeced67053944f13b0b.tar.bz2 |
re PR c/35701 (Quieten -Wconversion warnings)
2008-08-20 Manuel Lopez-Ibanez <manu@gcc.gnu.org>
PR 35701
* c-common.c (conversion_warning): Do not warn if applying bit-and
operator to unsigned constant that fits in the target type.
testsuite/
* gcc.dg/pr35701.c: New.
* gcc.dg/Wconversion-real-integer.c: Add more tests.
* gcc.dg/Wconversion-pr34389.c: Update.
* g++.dg/warn/Wconversion-pr34389.C: Update.
From-SVN: r139329
-rw-r--r-- | gcc/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/c-common.c | 18 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/warn/Wconversion-pr34389.C | 5 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/warn/Wconversion-real-integer.C | 41 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/Wconversion-pr34389.c | 4 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/Wconversion-real-integer.c | 40 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/pr35701.c | 31 |
8 files changed, 145 insertions, 8 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 9560a7b..956d401 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,11 @@ 2008-08-20 Manuel Lopez-Ibanez <manu@gcc.gnu.org> + PR 35701 + * c-common.c (conversion_warning): Do not warn if applying bit-and + operator to unsigned constant that fits in the target type. + +2008-08-20 Manuel Lopez-Ibanez <manu@gcc.gnu.org> + PR c++/35602 * c-common.c (conversion_warning): Do not warn for artificial expressions. diff --git a/gcc/c-common.c b/gcc/c-common.c index 92e58c9..bb420ba 100644 --- a/gcc/c-common.c +++ b/gcc/c-common.c @@ -1693,13 +1693,16 @@ conversion_warning (tree type, tree expr) TREE_OPERAND (expr, 1), /* bitwise */1); - /* If one of the operands is a non-negative constant - that fits in the target type, then the type of the - other operand does not matter. */ if (TREE_CODE (expr) == BIT_AND_EXPR) { tree op0 = TREE_OPERAND (expr, 0); tree op1 = TREE_OPERAND (expr, 1); + bool unsigned0 = TYPE_UNSIGNED (TREE_TYPE (op0)); + bool unsigned1 = TYPE_UNSIGNED (TREE_TYPE (op1)); + + /* If one of the operands is a non-negative constant + that fits in the target type, then the type of the + other operand does not matter. */ if ((TREE_CODE (op0) == INTEGER_CST && int_fits_type_p (op0, c_common_signed_type (type)) && int_fits_type_p (op0, c_common_unsigned_type (type))) @@ -1708,6 +1711,15 @@ conversion_warning (tree type, tree expr) && int_fits_type_p (op1, c_common_unsigned_type (type)))) return; + /* If constant is unsigned and fits in the target + type, then the result will also fit. */ + else if ((TREE_CODE (op0) == INTEGER_CST + && unsigned0 + && int_fits_type_p (op0, type)) + || (TREE_CODE (op1) == INTEGER_CST + && unsigned1 + && int_fits_type_p (op1, type))) + return; } } /* Warn for integer types converted to smaller integer types. */ diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 2c87d83..2a6c60e 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,13 @@ 2008-08-20 Manuel Lopez-Ibanez <manu@gcc.gnu.org> + PR 35701 + * gcc.dg/pr35701.c: New. + * gcc.dg/Wconversion-real-integer.c: Add more tests. + * gcc.dg/Wconversion-pr34389.c: Update. + * g++.dg/warn/Wconversion-pr34389.C: Update. + +2008-08-20 Manuel Lopez-Ibanez <manu@gcc.gnu.org> + PR c++/35602 * g++.dg/warn/pr35602.C: New. diff --git a/gcc/testsuite/g++.dg/warn/Wconversion-pr34389.C b/gcc/testsuite/g++.dg/warn/Wconversion-pr34389.C index f3cd310..a6df403 100644 --- a/gcc/testsuite/g++.dg/warn/Wconversion-pr34389.C +++ b/gcc/testsuite/g++.dg/warn/Wconversion-pr34389.C @@ -1,7 +1,7 @@ /* PR 34389 */ /* { dg-do compile } */ /* { dg-options "-Wconversion -Wsign-conversion" } */ - +/* { dg-require-effective-target int32plus } */ short mask1(short x) { short y = 0x7fff; @@ -32,7 +32,8 @@ short mask3(int si, unsigned int ui) us = si & 0x7fff; us = si & 0xAAAA; /* { dg-warning "conversion" } */ us = ui & 0x7fff; - us = ui & 0xAAAA; /* { dg-warning "conversion" } */ + us = ui & 0xAAAA; /* 0xAAAA is zero-extended, thus it masks the + upper bits of 'ui' making it fit in 'us'. */ return ss; } diff --git a/gcc/testsuite/g++.dg/warn/Wconversion-real-integer.C b/gcc/testsuite/g++.dg/warn/Wconversion-real-integer.C index 64d5199..282ac13 100644 --- a/gcc/testsuite/g++.dg/warn/Wconversion-real-integer.C +++ b/gcc/testsuite/g++.dg/warn/Wconversion-real-integer.C @@ -4,7 +4,7 @@ /* { dg-do compile } /* { dg-options "-Wconversion" } */ - +/* { dg-require-effective-target int32plus } */ #include <limits.h> void fsi (signed int x); @@ -71,3 +71,42 @@ void h (void) } +void fss (signed short x); +void fus (unsigned short x); +void fsc (signed char x); +void fuc (unsigned char x); + +void h2 (void) +{ + unsigned short int us; + short int ss; + unsigned char uc; + signed char sc; + + fss (4294967294.0); /* { dg-warning "conversion" } */ + ss = 4294967294.0; /* { dg-warning "conversion" } */ + fss (-4294967294.0); /* { dg-warning "conversion" } */ + ss = -4294967294.0; /* { dg-warning "conversion" } */ + fus (4294967294.0); /* { dg-warning "conversion" } */ + us = 4294967294.0; /* { dg-warning "conversion" } */ + fus (-4294967294.0); /* { dg-warning "conversion" } */ + us = -4294967294.0; /* { dg-warning "conversion" } */ + + fsc (500.0); /* { dg-warning "conversion" } */ + sc = 500.0; /* { dg-warning "conversion" } */ + fsc (-500.0); /* { dg-warning "conversion" } */ + sc = -500.0; /* { dg-warning "conversion" } */ + fuc (500.0); /* { dg-warning "conversion" } */ + uc = 500.0; /* { dg-warning "conversion" } */ + fuc (-500.0); /* { dg-warning "conversion" } */ + uc = -500.0; /* { dg-warning "conversion" } */ + + fss (500.0); + ss = 500.0; + fss (-500.0); + ss = -500.0; + fus (500.0); + us = 500.0; + fus (-500.0); /* { dg-warning "conversion" } */ + us = -500.0; /* { dg-warning "conversion" } */ +} diff --git a/gcc/testsuite/gcc.dg/Wconversion-pr34389.c b/gcc/testsuite/gcc.dg/Wconversion-pr34389.c index 45cdf19..1a43368 100644 --- a/gcc/testsuite/gcc.dg/Wconversion-pr34389.c +++ b/gcc/testsuite/gcc.dg/Wconversion-pr34389.c @@ -1,6 +1,7 @@ /* PR 34389 */ /* { dg-do compile } */ /* { dg-options "-Wconversion -Wsign-conversion" } */ +/* { dg-require-effective-target int32plus } */ short mask1(short x) { @@ -32,7 +33,8 @@ short mask3(int si, unsigned int ui) us = si & 0x7fff; us = si & 0xAAAA; /* { dg-warning "conversion" } */ us = ui & 0x7fff; - us = ui & 0xAAAA; /* { dg-warning "conversion" } */ + us = ui & 0xAAAA; /* 0xAAAA is zero-extended, thus it masks the + upper bits of 'ui' making it fit in 'us'. */ return ss; } diff --git a/gcc/testsuite/gcc.dg/Wconversion-real-integer.c b/gcc/testsuite/gcc.dg/Wconversion-real-integer.c index 1c03ba4..1625fc0 100644 --- a/gcc/testsuite/gcc.dg/Wconversion-real-integer.c +++ b/gcc/testsuite/gcc.dg/Wconversion-real-integer.c @@ -4,7 +4,7 @@ /* { dg-do compile } /* { dg-skip-if "doubles are floats,ints are 16bits" { "avr-*-*" } { "*" } { "" } } */ /* { dg-options "-std=c99 -Wconversion" } */ - +/* { dg-require-effective-target int32plus } */ #include <limits.h> void fsi (signed int x); @@ -71,4 +71,42 @@ void h (void) } +void fss (signed short x); +void fus (unsigned short x); +void fsc (signed char x); +void fuc (unsigned char x); + +void h2 (void) +{ + unsigned short int us; + short int ss; + unsigned char uc; + signed char sc; + + fss (4294967294.0); /* { dg-warning "conversion" } */ + ss = 4294967294.0; /* { dg-warning "conversion" } */ + fss (-4294967294.0); /* { dg-warning "conversion" } */ + ss = -4294967294.0; /* { dg-warning "conversion" } */ + fus (4294967294.0); /* { dg-warning "conversion" } */ + us = 4294967294.0; /* { dg-warning "conversion" } */ + fus (-4294967294.0); /* { dg-warning "conversion" } */ + us = -4294967294.0; /* { dg-warning "conversion" } */ + fsc (500.0); /* { dg-warning "conversion" } */ + sc = 500.0; /* { dg-warning "conversion" } */ + fsc (-500.0); /* { dg-warning "conversion" } */ + sc = -500.0; /* { dg-warning "conversion" } */ + fuc (500.0); /* { dg-warning "conversion" } */ + uc = 500.0; /* { dg-warning "conversion" } */ + fuc (-500.0); /* { dg-warning "conversion" } */ + uc = -500.0; /* { dg-warning "conversion" } */ + + fss (500.0); + ss = 500.0; + fss (-500.0); + ss = -500.0; + fus (500.0); + us = 500.0; + fus (-500.0); /* { dg-warning "conversion" } */ + us = -500.0; /* { dg-warning "conversion" } */ +} diff --git a/gcc/testsuite/gcc.dg/pr35701.c b/gcc/testsuite/gcc.dg/pr35701.c new file mode 100644 index 0000000..4144430 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr35701.c @@ -0,0 +1,31 @@ +/* PR 35701 */ +/* { dg-do compile } */ +/* { dg-options "-Wconversion -Wsign-conversion" } */ +/* { dg-require-effective-target int32plus } */ + +typedef struct _my_struct_t { + unsigned int small:1; + unsigned int big:31; +} my_struct_t, *my_struct_p_t; + +void +my_func1(unsigned int sm, unsigned int bi, my_struct_p_t msp) +{ + msp->small = sm; /* { dg-warning "conversion" } */ + msp->big = bi; /* { dg-warning "conversion" } */ +} + +void +my_func2(unsigned int sm, unsigned int bi, my_struct_p_t msp) +{ + msp->small = sm & 1U; + msp->big = bi & 0x7fffffffU; +} + +unsigned short +my_func3(unsigned int sm) +{ + unsigned short res; + res = sm & 0xff20U; + return res; +} |