Patchwork [C++] PR 19618

login
register
mail settings
Submitter Paolo Carlini
Date May 24, 2013, 12:24 p.m.
Message ID <519F5C0C.2050204@oracle.com>
Download mbox | patch
Permalink /patch/246134/
State New
Headers show

Comments

Paolo Carlini - May 24, 2013, 12:24 p.m.
Hi,

I think we can resolve this very old issue too: we don't warn at all for 
bitfields of size exceeding the type when it's bool or enum. I have no 
idea why historically we decided to not do that, but certainly all the 
modern compilers I have at hand do warn, by default, thus it seems safe 
to at least pedwarn, or even simply warn, if you like.

Patch booted and tested x86_64-linux.

Thanks,
Paolo.

//////////////////////////
/cp
2013-05-24  Paolo Carlini  <paolo.carlini@oracle.com>

	PR c++/19618
	* class.c (check_bitfield_decl): Pedwarn for bool and enum bitfields
	with width exceeding the type.

/testsuite
2013-05-24  Paolo Carlini  <paolo.carlini@oracle.com>

	PR c++/19618
	* g++.dg/expr/bitfield12.C: New.
	* g++.dg/expr/bitfield1.C: Adjust.
	* g++.dg/expr/bitfield3.C: Likewise.
	* g++.dg/expr/bitfield4.C: Likewise.
	* g++.dg/expr/bitfield5.C: Likewise.
	* g++.dg/expr/bitfield6.C: Likewise.
	* g++.old-deja/g++.jason/bool2.C: Likewise.
Jason Merrill - May 24, 2013, 1:36 p.m.
Why would we want to pedwarn?  As far as I can tell, the standard 
doesn't say this is ill-formed.  9.6 says,

"The value of the integral constant expression may be larger than the 
number of bits in the object representation (3.9) of the bit-field’s 
type; in such cases the extra bits are used as padding bits and do not 
participate in the value representation (3.9) of the bit-field."

and

"A bool value can successfully be stored in a bit-field of any nonzero 
size."

I'm sure that lots of users would complain about the compiler starting 
to reject bool bitfields of 2-8 bits.

I'm not opposed to warning about excessive size for bool and enum here, 
but the warning should be based on TYPE_SIZE rather than TYPE_PRECISION.

Jason

Patch

Index: cp/class.c
===================================================================
--- cp/class.c	(revision 199287)
+++ cp/class.c	(working copy)
@@ -3140,10 +3140,15 @@  check_bitfield_decl (tree field)
 	  error ("zero width for bit-field %q+D", field);
 	  w = error_mark_node;
 	}
-      else if (compare_tree_int (w, TYPE_PRECISION (type)) > 0
-	       && TREE_CODE (type) != ENUMERAL_TYPE
-	       && TREE_CODE (type) != BOOLEAN_TYPE)
-	warning (0, "width of %q+D exceeds its type", field);
+      else if (compare_tree_int (w, TYPE_PRECISION (type)) > 0)
+	{
+	  if (TREE_CODE (type) == ENUMERAL_TYPE
+	      || TREE_CODE (type) == BOOLEAN_TYPE)
+	    pedwarn (input_location, OPT_Wpedantic,
+		     "width of %q+D exceeds its type", field);
+	  else
+	    warning (0, "width of %q+D exceeds its type", field);
+	}
       else if (TREE_CODE (type) == ENUMERAL_TYPE
 	       && (0 > (compare_tree_int
 			(w, TYPE_PRECISION (ENUM_UNDERLYING_TYPE (type))))))
Index: testsuite/g++.dg/expr/bitfield1.C
===================================================================
--- testsuite/g++.dg/expr/bitfield1.C	(revision 199288)
+++ testsuite/g++.dg/expr/bitfield1.C	(working copy)
@@ -1,4 +1,5 @@ 
 // PR c++/27505
+// { dg-options "" }
 
 struct s {
   bool field:8;
Index: testsuite/g++.dg/expr/bitfield12.C
===================================================================
--- testsuite/g++.dg/expr/bitfield12.C	(revision 0)
+++ testsuite/g++.dg/expr/bitfield12.C	(working copy)
@@ -0,0 +1,11 @@ 
+// PR c++/19618
+
+struct bset1 {
+  bool bit : 93111;    // { dg-error "exceeds" }
+};
+
+enum E {};
+
+struct bset2 {
+  E bit : 93111;       // { dg-error "exceeds" }
+};
Index: testsuite/g++.dg/expr/bitfield3.C
===================================================================
--- testsuite/g++.dg/expr/bitfield3.C	(revision 199288)
+++ testsuite/g++.dg/expr/bitfield3.C	(working copy)
@@ -1,4 +1,5 @@ 
 // PR c++/30274
+// { dg-options "" }
 
 struct S {
   bool x : 4;
Index: testsuite/g++.dg/expr/bitfield4.C
===================================================================
--- testsuite/g++.dg/expr/bitfield4.C	(revision 199288)
+++ testsuite/g++.dg/expr/bitfield4.C	(working copy)
@@ -1,5 +1,6 @@ 
 // PR c++/30274
 // { dg-do link }
+// { dg-options "" }
 
 struct S {
   bool x : 4;
Index: testsuite/g++.dg/expr/bitfield5.C
===================================================================
--- testsuite/g++.dg/expr/bitfield5.C	(revision 199288)
+++ testsuite/g++.dg/expr/bitfield5.C	(working copy)
@@ -1,5 +1,6 @@ 
 // PR c++/30274
 // { dg-do run }
+// { dg-options "" }
 
 struct S {
   bool x : 4;
Index: testsuite/g++.dg/expr/bitfield6.C
===================================================================
--- testsuite/g++.dg/expr/bitfield6.C	(revision 199288)
+++ testsuite/g++.dg/expr/bitfield6.C	(working copy)
@@ -1,4 +1,5 @@ 
 // PR c++/30274
+// { dg-options "" }
 
 struct S {
   bool x : 4;
Index: testsuite/g++.old-deja/g++.jason/bool2.C
===================================================================
--- testsuite/g++.old-deja/g++.jason/bool2.C	(revision 199287)
+++ testsuite/g++.old-deja/g++.jason/bool2.C	(working copy)
@@ -1,4 +1,5 @@ 
 // { dg-do run  }
+// { dg-options "" }
 // Make sure that bool bitfields promote to int properly.
 
 struct F {