This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
C++ PATCH: PR 27803
- From: Mark Mitchell <mark at codesourcery dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Tue, 30 May 2006 14:29:15 -0700
- Subject: C++ PATCH: PR 27803
- Reply-to: mark at codesourcery dot com
Volker discovered that my recent bitfield patches caused an ICE (after
an error message) on the invalid program in the attached patch. This
is another case where the C++ front-end let an invalid bit of C++
(namely, a bit-field with non-integral type) leak past the point of
detection. My patches never expected to see such a bitfield, so they
blew up.
Fixed by giving such a bitfield an error type at the point that the
error message is issued. (It would be even better to collapse
check_bitfield_decl into grokbitfield, but I didn't want to tackle
that right now.)
Tested on x86_64-unknown-linux-gnu, applied on the mainline.
--
Mark Mitchell
CodeSourcery
mark@codesourcery.com
(650) 331-3385 x713
2006-05-30 Mark Mitchell <mark@codesourcery.com>
PR c++/27803
* class.c (check_bitfield_decl): Ensure that all bitfields have
integral type.
2006-05-30 Mark Mitchell <mark@codesourcery.com>
PR c++/27803
* g++.dg/parse/bitfield1.C: New test.
Index: gcc/cp/class.c
===================================================================
--- gcc/cp/class.c (revision 114207)
+++ gcc/cp/class.c (working copy)
@@ -2625,21 +2625,25 @@ static void
check_bitfield_decl (tree field)
{
tree type = TREE_TYPE (field);
- tree w = NULL_TREE;
+ tree w;
+
+ /* Extract the declared width of the bitfield, which has been
+ temporarily stashed in DECL_INITIAL. */
+ w = DECL_INITIAL (field);
+ gcc_assert (w != NULL_TREE);
+ /* Remove the bit-field width indicator so that the rest of the
+ compiler does not treat that value as an initializer. */
+ DECL_INITIAL (field) = NULL_TREE;
/* Detect invalid bit-field type. */
- if (DECL_INITIAL (field)
- && ! INTEGRAL_TYPE_P (TREE_TYPE (field)))
+ if (!INTEGRAL_TYPE_P (type))
{
error ("bit-field %q+#D with non-integral type", field);
+ TREE_TYPE (field) = error_mark_node;
w = error_mark_node;
}
-
- /* Detect and ignore out of range field width. */
- if (DECL_INITIAL (field))
+ else
{
- w = DECL_INITIAL (field);
-
/* Avoid the non_lvalue wrapper added by fold for PLUS_EXPRs. */
STRIP_NOPS (w);
@@ -2676,10 +2680,6 @@ check_bitfield_decl (tree field)
warning (0, "%q+D is too small to hold all values of %q#T", field, type);
}
- /* Remove the bit-field width indicator so that the rest of the
- compiler does not treat that value as an initializer. */
- DECL_INITIAL (field) = NULL_TREE;
-
if (w != error_mark_node)
{
DECL_SIZE (field) = convert (bitsizetype, w);
Index: gcc/testsuite/g++.dg/parse/bitfield1.C
===================================================================
--- gcc/testsuite/g++.dg/parse/bitfield1.C (revision 0)
+++ gcc/testsuite/g++.dg/parse/bitfield1.C (revision 0)
@@ -0,0 +1,11 @@
+// PR c++/27803
+
+struct A
+{
+ double i : 8; // { dg-error "type" }
+};
+
+void foo(A& a)
+{
+ (char)a.i;
+}