This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

C++ PATCH: PR 27803


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;
+}


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]