aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorManuel López-Ibáñez <manu@gcc.gnu.org>2008-08-20 16:09:45 +0000
committerManuel López-Ibáñez <manu@gcc.gnu.org>2008-08-20 16:09:45 +0000
commit9c591bd0849e4ed59a584aeced67053944f13b0b (patch)
treee4b280fa4d233f4a7258a47cdc899fe8254038f0
parent0011dedbd9dbfa01b2f4d3390ef3ed2d6ea1dd6d (diff)
downloadgcc-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/ChangeLog6
-rw-r--r--gcc/c-common.c18
-rw-r--r--gcc/testsuite/ChangeLog8
-rw-r--r--gcc/testsuite/g++.dg/warn/Wconversion-pr34389.C5
-rw-r--r--gcc/testsuite/g++.dg/warn/Wconversion-real-integer.C41
-rw-r--r--gcc/testsuite/gcc.dg/Wconversion-pr34389.c4
-rw-r--r--gcc/testsuite/gcc.dg/Wconversion-real-integer.c40
-rw-r--r--gcc/testsuite/gcc.dg/pr35701.c31
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;
+}