aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2008-11-13 19:38:20 -0500
committerJason Merrill <jason@gcc.gnu.org>2008-11-13 19:38:20 -0500
commit2d727f75f1b00ebb9269b573c022b11280c09c31 (patch)
treee1b712fe6fd456e38f890070bb379fee30d6f1f0 /gcc
parent03c715aa1d8a984529cbf1b84020de9ea8746e17 (diff)
downloadgcc-2d727f75f1b00ebb9269b573c022b11280c09c31.zip
gcc-2d727f75f1b00ebb9269b573c022b11280c09c31.tar.gz
gcc-2d727f75f1b00ebb9269b573c022b11280c09c31.tar.bz2
re PR c++/37932 (narrowing conversion with -std=c++0x)
PR c++/37932 * typeck2.c (process_init_constructor_record): Update bitfield handling. (check_narrowing): Update bitfield handling, print source type. From-SVN: r141843
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog7
-rw-r--r--gcc/cp/typeck2.c17
-rw-r--r--gcc/testsuite/ChangeLog6
-rw-r--r--gcc/testsuite/g++.dg/conversion/bitfield11.C8
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/initlist7.C12
5 files changed, 46 insertions, 4 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 0a956d8..2c936ef 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -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
diff --git a/gcc/cp/typeck2.c b/gcc/cp/typeck2.c
index bf0ff6b..207dd99 100644
--- a/gcc/cp/typeck2.c
+++ b/gcc/cp/typeck2.c
@@ -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);
}
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index de5809e..898aaf2 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
index 0000000..e36539c
--- /dev/null
+++ b/gcc/testsuite/g++.dg/conversion/bitfield11.C
@@ -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
index 0000000..7913ed7
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/initlist7.C
@@ -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};
+}