]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR c/35701 (Quieten -Wconversion warnings)
authorManuel López-Ibáñez <manu@gcc.gnu.org>
Wed, 20 Aug 2008 16:09:45 +0000 (16:09 +0000)
committerManuel López-Ibáñez <manu@gcc.gnu.org>
Wed, 20 Aug 2008 16:09:45 +0000 (16:09 +0000)
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

gcc/ChangeLog
gcc/c-common.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/warn/Wconversion-pr34389.C
gcc/testsuite/g++.dg/warn/Wconversion-real-integer.C
gcc/testsuite/gcc.dg/Wconversion-pr34389.c
gcc/testsuite/gcc.dg/Wconversion-real-integer.c
gcc/testsuite/gcc.dg/pr35701.c [new file with mode: 0644]

index 9560a7bcc545d912c57eaa074232ba117b7e7267..956d401a6d6ce3129d94735e4b54ed518e2caba3 100644 (file)
@@ -1,3 +1,9 @@
+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
index 92e58c9fb00d8e44f219a4d535a4c3956c47f106..bb420ba72c7a412d92b6ef2043781d20d265aec8 100644 (file)
@@ -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.  */
index 2c87d83e5ea6b305881156299c8e774de0c9293b..2a6c60eaaf010a526f29af9cff06defea359383f 100644 (file)
@@ -1,3 +1,11 @@
+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
index f3cd310538690a7a88fc8f8867bab4f27103c4e9..a6df4035a6242d27d3d35f7f1cc5a5d897114cc9 100644 (file)
@@ -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;
 }
index 64d5199bcd54b9b3cb4d9723b03879dd70720965..282ac13da582d835b78888aaeeb8c85733fd6f80 100644 (file)
@@ -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" } */
+}
index 45cdf19ef711bb010dfbe8a734a3a7721bbc1e03..1a4336802606e5c40e27a50e63a83cad2e9c0202 100644 (file)
@@ -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;
 }
index 1c03ba487e35ddb832fc54b4254d4f0152dee5d5..1625fc03581a36e30d11c24335466e4660c91098 100644 (file)
@@ -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 (file)
index 0000000..4144430
--- /dev/null
@@ -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;
+}