Patchwork [C++] PR 19618

login
register
mail settings
Submitter Paolo Carlini
Date May 24, 2013, 2:50 p.m.
Message ID <519F7E2B.9000201@oracle.com>
Download mbox | patch
Permalink /patch/246188/
State New
Headers show

Comments

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

On 05/24/2013 03:36 PM, Jason Merrill wrote:
> 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.
Thanks Jason. Shame on me, I was totally confused, I guess I need some 
time off (*).
> 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.
Makes perfect sense. Thus I'm finishing testing the below. Better?

Thanks again,
Paolo.

(*) For real, next week vacations for me.

////////////////////////
Jason Merrill - May 24, 2013, 4:12 p.m.
On 05/24/2013 10:50 AM, Paolo Carlini wrote:
> +	       || ((TREE_CODE (type) == ENUMERAL_TYPE
> +		    && (tree_int_cst_lt
> +			(TYPE_SIZE (ENUM_UNDERLYING_TYPE (type)), w)))
> +		   || (TREE_CODE (type) == BOOLEAN_TYPE
> +		       && tree_int_cst_lt (TYPE_SIZE (type), w))))

The size of the enum underlying type is the same as the size of the enum 
itself, so I don't think you need to handle enum and bool differently here.

Jason

Patch

Index: cp/class.c
===================================================================
--- cp/class.c	(revision 199287)
+++ cp/class.c	(working copy)
@@ -3140,9 +3140,14 @@  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)
+      else if ((TREE_CODE (type) != ENUMERAL_TYPE
+		&& TREE_CODE (type) != BOOLEAN_TYPE
+		&& compare_tree_int (w, TYPE_PRECISION (type)) > 0)
+	       || ((TREE_CODE (type) == ENUMERAL_TYPE
+		    && (tree_int_cst_lt
+			(TYPE_SIZE (ENUM_UNDERLYING_TYPE (type)), w)))
+		   || (TREE_CODE (type) == BOOLEAN_TYPE
+		       && tree_int_cst_lt (TYPE_SIZE (type), w))))
 	warning (0, "width of %q+D exceeds its type", field);
       else if (TREE_CODE (type) == ENUMERAL_TYPE
 	       && (0 > (compare_tree_int
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,19 @@ 
+// PR c++/19618
+
+struct bset1 {
+  bool bit : sizeof(bool) * __CHAR_BIT__ + 1;  // { dg-warning "exceeds" }
+};
+
+enum E {};
+
+struct bset2 {
+  E bit : sizeof(__underlying_type(E)) * __CHAR_BIT__ + 1; // { dg-warning "exceeds" }
+};
+
+struct bset3 {
+  bool bit : sizeof(bool) * __CHAR_BIT__;
+};
+
+struct bset4 {
+  E bit : sizeof(__underlying_type(E)) * __CHAR_BIT__;
+};