re PR c++/37932 (narrowing conversion with -std=c++0x)
authorJason Merrill <jason@redhat.com>
Fri, 14 Nov 2008 00:38:20 +0000 (19:38 -0500)
committerJason Merrill <jason@gcc.gnu.org>
Fri, 14 Nov 2008 00:38:20 +0000 (19:38 -0500)
        PR c++/37932
        * typeck2.c (process_init_constructor_record): Update bitfield
        handling.
        (check_narrowing): Update bitfield handling, print source type.

From-SVN: r141843

gcc/cp/ChangeLog
gcc/cp/typeck2.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/conversion/bitfield11.C [new file with mode: 0644]
gcc/testsuite/g++.dg/cpp0x/initlist7.C [new file with mode: 0644]

index 0a956d835844fa405347d8aee50635c2f20d4341..2c936efc99b4d62cb4ddf1b7cb70b55a9ea8d19b 100644 (file)
@@ -1,3 +1,10 @@
+2008-11-13  Jason Merrill  <jason@redhat.com>
+
+       PR c++/37932
+       * typeck2.c (process_init_constructor_record): Update bitfield
+       handling.
+       (check_narrowing): Update bitfield handling, print source type.
+       
 2008-11-12  Jakub Jelinek  <jakub@redhat.com>
 
        PR c++/36478
index bf0ff6b11757e74329202926ba66afd94bc34150..207dd9917d9db1f6ff4d1ccc8af1b165cea736e1 100644 (file)
@@ -650,7 +650,7 @@ store_init_value (tree decl, tree init)
 void
 check_narrowing (tree type, tree init)
 {
-  tree ftype = TREE_TYPE (init);
+  tree ftype = unlowered_expr_type (init);
   bool ok = true;
   REAL_VALUE_TYPE d;
   bool was_decl = false;
@@ -704,8 +704,8 @@ check_narrowing (tree type, tree init)
     }
 
   if (!ok)
-    permerror (input_location, "narrowing conversion of %qE to %qT inside { }",
-              init, type);
+    permerror (input_location, "narrowing conversion of %qE from %qT to %qT inside { }",
+              init, ftype, type);
 }
 
 /* Process the initializer INIT for a variable of type TYPE, emitting
@@ -993,6 +993,7 @@ process_init_constructor_record (tree type, tree init)
   for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
     {
       tree next;
+      tree type;
 
       if (!DECL_NAME (field) && DECL_C_BIT_FIELD (field))
        {
@@ -1004,6 +1005,11 @@ process_init_constructor_record (tree type, tree init)
       if (TREE_CODE (field) != FIELD_DECL || DECL_ARTIFICIAL (field))
        continue;
 
+      /* If this is a bitfield, first convert to the declared type.  */
+      type = TREE_TYPE (field);
+      if (DECL_BIT_FIELD_TYPE (field))
+       type = DECL_BIT_FIELD_TYPE (field);
+
       if (idx < VEC_length (constructor_elt, CONSTRUCTOR_ELTS (init)))
        {
          constructor_elt *ce = VEC_index (constructor_elt,
@@ -1024,7 +1030,7 @@ process_init_constructor_record (tree type, tree init)
            }
 
          gcc_assert (ce->value);
-         next = digest_init_r (TREE_TYPE (field), ce->value, true);
+         next = digest_init_r (type, ce->value, true);
          ++idx;
        }
       else if (TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (field)))
@@ -1068,6 +1074,9 @@ process_init_constructor_record (tree type, tree init)
            continue;
        }
 
+      /* If this is a bitfield, now convert to the lowered type.  */
+      if (type != TREE_TYPE (field))
+       next = cp_convert_and_check (TREE_TYPE (field), next);
       flags |= picflag_from_initializer (next);
       CONSTRUCTOR_APPEND_ELT (v, field, next);
     }
index de5809e1938ae70c03011ff545d1a5cd41f8ff62..898aaf24150373e661f1d50a82e90cce83a3c449 100644 (file)
@@ -1,3 +1,9 @@
+2008-11-13  Jason Merrill  <jason@redhat.com>
+
+       PR c++/37932
+       * g++.dg/conversion/bitfield11.C: New test.
+       * g++.dg/cpp0x/initlist7.C: New test.
+
 2008-11-13  Richard Sandiford  <rdsandiford@googlemail.com>
 
        * gcc.target/mips/loongson-muldiv-1.c: New test.
diff --git a/gcc/testsuite/g++.dg/conversion/bitfield11.C b/gcc/testsuite/g++.dg/conversion/bitfield11.C
new file mode 100644 (file)
index 0000000..e36539c
--- /dev/null
@@ -0,0 +1,8 @@
+// Make sure that digest_init converts to the declared type of the
+// bitfield, not just the lowered type.
+
+enum E { EA, EB };
+
+struct A { E e: 8; };
+
+A a = { 0 };                   // { dg-error "invalid conversion" }
diff --git a/gcc/testsuite/g++.dg/cpp0x/initlist7.C b/gcc/testsuite/g++.dg/cpp0x/initlist7.C
new file mode 100644 (file)
index 0000000..7913ed7
--- /dev/null
@@ -0,0 +1,12 @@
+// PR c++/37932
+// { dg-options "-std=c++0x" }
+
+typedef enum { AA=1, BB=2 } my_enum;
+
+typedef struct { my_enum a:4 ; unsigned b:28; } stru;
+
+void foo (char c, my_enum x, int i)
+{
+  char arr[2] = {c+'0', 0};    // { dg-error "narrowing" }
+  stru s = {x,0};
+}