]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR c++/38007 (g++ instantiate same operator twice due to bitfield in -O0 mode...
authorJason Merrill <jason@redhat.com>
Wed, 12 Nov 2008 20:50:45 +0000 (15:50 -0500)
committerJason Merrill <jason@gcc.gnu.org>
Wed, 12 Nov 2008 20:50:45 +0000 (15:50 -0500)
        PR c++/38007
gcc/cp/
        * typeck.c (cp_build_modify_expr): Update bitfield handling.
gcc/
        * c-common.c (c_common_signed_or_unsigned_type): Remove C++
        special casing.
gcc/testsuite/
        * g++.dg/conversion/bitfield10.C: New test.
        * g++.dg/warn/pr35635.C (func1): Accept additional warning.
        * g++.old-deja/g++.mike/enum1.C: Expect warn about assignment.
        * g++.dg/expr/bitfield9.C: Pass -Wno-overflow.

From-SVN: r141800

gcc/ChangeLog
gcc/c-common.c
gcc/cp/ChangeLog
gcc/cp/typeck.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/conversion/bitfield10.C [new file with mode: 0644]
gcc/testsuite/g++.dg/expr/bitfield9.C
gcc/testsuite/g++.dg/warn/pr35635.C
gcc/testsuite/g++.old-deja/g++.mike/enum1.C

index 03767f47c284ec7b1f8deb89711301adf9d830e8..e0c09c482217393d233dad22cc2a7545f217a795 100644 (file)
@@ -1,3 +1,9 @@
+2008-11-12  Jason Merrill  <jason@redhat.com>
+
+       PR c++/38007
+       * c-common.c (c_common_signed_or_unsigned_type): Remove C++
+       special casing.
+
 2008-11-12  Anatoly Sokolov  <aesok@post.ru>
 
        * config/avr/avr.c (avr_mcu_t): Add atmega16hvb, atmega32hvb,
index ea7379edc5c56c2ce2f47220284c660dd3f0cc59..df8281711e943e4ec3962f5511cedce0431a1950 100644 (file)
@@ -2719,7 +2719,7 @@ c_common_signed_or_unsigned_type (int unsignedp, tree type)
 
 #define TYPE_OK(node)                                                      \
   (TYPE_MODE (type) == TYPE_MODE (node)                                            \
-   && (c_dialect_cxx () || TYPE_PRECISION (type) == TYPE_PRECISION (node)))
+   && TYPE_PRECISION (type) == TYPE_PRECISION (node))
   if (TYPE_OK (signed_char_type_node))
     return unsignedp ? unsigned_char_type_node : signed_char_type_node;
   if (TYPE_OK (integer_type_node))
@@ -2749,10 +2749,7 @@ c_common_signed_or_unsigned_type (int unsignedp, tree type)
     return unsignedp ? unsigned_intQI_type_node : intQI_type_node;
 #undef TYPE_OK
 
-  if (c_dialect_cxx ())
-    return type;
-  else
-    return build_nonstandard_integer_type (TYPE_PRECISION (type), unsignedp);
+  return build_nonstandard_integer_type (TYPE_PRECISION (type), unsignedp);
 }
 
 /* Build a bit-field integer type for the given WIDTH and UNSIGNEDP.  */
index c19dc815467a4c60ada3ff5f0e40cf629b40245d..769e4cbc75540ae8aa8227b7323b6dd9466bc7ec 100644 (file)
@@ -1,3 +1,8 @@
+2008-11-12  Jason Merrill  <jason@redhat.com>
+
+       PR c++/38007
+       * typeck.c (cp_build_modify_expr): Update bitfield handling.
+
 2008-11-12  Jakub Jelinek  <jakub@redhat.com>
 
        PR c++/34269
index 84ebc953a9a1d916189b8e6c9d9f7d065b1302b3..321f76b32702cefc0aafeca75f83465640c5acb4 100644 (file)
@@ -5801,7 +5801,6 @@ cp_build_modify_expr (tree lhs, enum tree_code modifycode, tree rhs,
   tree newrhs = rhs;
   tree lhstype = TREE_TYPE (lhs);
   tree olhstype = lhstype;
-  tree olhs = NULL_TREE;
   bool plain_assign = (modifycode == NOP_EXPR);
 
   /* Avoid duplicate error messages from operands that had errors.  */
@@ -6005,35 +6004,11 @@ cp_build_modify_expr (tree lhs, enum tree_code modifycode, tree rhs,
        return error_mark_node;
     }
 
-  /* If storing into a structure or union member, it has probably been
-     given type `int'.  Compute the type that would go with the actual
-     amount of storage the member occupies.  */
+  /* If storing into a structure or union member, it may have been given a
+     lowered bitfield type.  We need to convert to the declared type first,
+     so retrieve it now.  */
 
-  if (TREE_CODE (lhs) == COMPONENT_REF
-      && (TREE_CODE (lhstype) == INTEGER_TYPE
-         || TREE_CODE (lhstype) == REAL_TYPE
-         || TREE_CODE (lhstype) == ENUMERAL_TYPE))
-    {
-      lhstype = TREE_TYPE (get_unwidened (lhs, 0));
-
-      /* If storing in a field that is in actuality a short or narrower
-        than one, we must store in the field in its actual type.  */
-
-      if (lhstype != TREE_TYPE (lhs))
-       {
-         /* Avoid warnings converting integral types back into enums for
-            enum bit fields.  */
-         if (TREE_CODE (lhstype) == INTEGER_TYPE
-             && TREE_CODE (olhstype) == ENUMERAL_TYPE)
-           {
-             if (TREE_SIDE_EFFECTS (lhs))
-               lhs = stabilize_reference (lhs);
-             olhs = lhs;
-           }
-         lhs = copy_node (lhs);
-         TREE_TYPE (lhs) = lhstype;
-       }
-    }
+  olhstype = unlowered_expr_type (lhs);
 
   /* Convert new value to destination type.  */
 
@@ -6073,22 +6048,18 @@ cp_build_modify_expr (tree lhs, enum tree_code modifycode, tree rhs,
     }
 
   if (modifycode == INIT_EXPR)
-    newrhs = convert_for_initialization (lhs, lhstype, newrhs, LOOKUP_NORMAL,
+    newrhs = convert_for_initialization (lhs, olhstype, newrhs, LOOKUP_NORMAL,
                                         "initialization", NULL_TREE, 0,
                                          complain);
   else
+    newrhs = convert_for_assignment (olhstype, newrhs, "assignment",
+                                    NULL_TREE, 0, complain);
+
+  if (!same_type_p (lhstype, olhstype))
+    newrhs = cp_convert_and_check (lhstype, newrhs);
+
+  if (modifycode != INIT_EXPR)
     {
-      /* Avoid warnings on enum bit fields.  */
-      if (TREE_CODE (olhstype) == ENUMERAL_TYPE
-         && TREE_CODE (lhstype) == INTEGER_TYPE)
-       {
-         newrhs = convert_for_assignment (olhstype, newrhs, "assignment",
-                                          NULL_TREE, 0, complain);
-         newrhs = convert_force (lhstype, newrhs, 0);
-       }
-      else
-       newrhs = convert_for_assignment (lhstype, newrhs, "assignment",
-                                        NULL_TREE, 0, complain);
       if (TREE_CODE (newrhs) == CALL_EXPR
          && TYPE_NEEDS_CONSTRUCTING (lhstype))
        newrhs = build_cplus_new (lhstype, newrhs);
@@ -6120,21 +6091,7 @@ cp_build_modify_expr (tree lhs, enum tree_code modifycode, tree rhs,
   if (!plain_assign)
     TREE_NO_WARNING (result) = 1;
 
-  /* If we got the LHS in a different type for storing in,
-     convert the result back to the nominal type of LHS
-     so that the value we return always has the same type
-     as the LHS argument.  */
-
-  if (olhstype == TREE_TYPE (result))
-    return result;
-  if (olhs)
-    {
-      result = build2 (COMPOUND_EXPR, olhstype, result, olhs);
-      TREE_NO_WARNING (result) = 1;
-      return result;
-    }
-  return convert_for_assignment (olhstype, result, "assignment",
-                                NULL_TREE, 0, complain);
+  return result;
 }
 
 tree
index 30764342dd1657d609d5b34343d67386f06d95a1..a14100fe312b9b60849d5ad33c5108a13443a85c 100644 (file)
@@ -1,3 +1,11 @@
+2008-11-12  Jason Merrill  <jason@redhat.com>
+
+       PR c++/38007
+       * g++.dg/conversion/bitfield10.C: New test.
+       * g++.dg/warn/pr35635.C (func1): Accept additional warning.
+       * g++.old-deja/g++.mike/enum1.C: Expect warn about assignment.
+       * g++.dg/expr/bitfield9.C: Pass -Wno-overflow.
+
 2008-11-12  Tobias Burnus  <burnus@net-b.de>
 
        PR fortran/38065
diff --git a/gcc/testsuite/g++.dg/conversion/bitfield10.C b/gcc/testsuite/g++.dg/conversion/bitfield10.C
new file mode 100644 (file)
index 0000000..f75504e
--- /dev/null
@@ -0,0 +1,24 @@
+// PR c++/38007
+// We need to use the conversion function to the declared type of a bitfield,
+// not the lowered bitfield type.
+// { dg-do link }
+
+struct A
+{
+  operator unsigned int() { return 42; }
+  operator unsigned char();
+};
+
+struct B
+{
+  unsigned int b : 8;
+};
+
+int
+main ()
+{
+  A u;
+  unsigned int v = u;
+  B w;
+  w.b = u;
+}
index 047b1bf5239cc05555e870daeba1bf567b5c1cc8..177f65b8800dbfc74b6040bb7799c9e709685920 100644 (file)
@@ -1,5 +1,6 @@
 // PR c++/32346
 // { dg-do run }
+// { dg-options "-Wno-overflow" }
 
 extern "C" void abort();
 
index d3b39a2b0c855b2e51cdee7db04009b4b82bf2b3..66ade8b28e12b5397463c60a1e2cea05525edf37 100644 (file)
@@ -32,7 +32,7 @@ void func1()
   /* At least one branch of ? does not fit in the destination, thus
      warn.  */
   unsigned_bit.x = bar != 0 ? 2 : 0; /* { dg-warning "conversion" } */
-  unsigned_bit.x = bar != 0 ? 0 : -1; /* { dg-warning "negative integer implicitly converted to unsigned type" } */
+  unsigned_bit.x = bar != 0 ? 0 : -1; /* { dg-warning "conver" } */
 }
 
 void func2()
index 0b1a0eeac146a126d9134ba662e55644468d1fa1..35b1df0898ad8a9d3db4cb4dcc9e8c02686588f9 100644 (file)
@@ -8,4 +8,4 @@ struct Type {
   void setBTK();
 };
 
-void Type::setBTK() { kind = DTK; }
+void Type::setBTK() { kind = DTK; } // { dg-warning "truncate" }