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 27292


This patch fixes PR c++/27292, fallout from the patch from c++/26534.
When it was pointed out that the 26534 patch accidentally fixed 16376,
I realized that the hunk I'd added in decay_conversion wasn't doing
anything, so I revert it with this patch.  I've also added a testcase
for 16376.  I've adjusted "rvalue" to fix 27292 and
perform_integral_promotions to correct another related problem, shown
here as bitfield1.C.  (We have to make sure that enums still are
treated as enums for promotion purposes, not short integer types.)

Tested on x86_64-unknown-linux-gnu, applied to mainline.

(I do not plan to backport either this or the 26534 patch to 4.1;
instead, we'll use the more conservative masking of values assigned to
bitfields for 4.1, as an alternative fix for 26534.)

--
Mark Mitchell
CodeSourcery
mark@codesourcery.com
(650) 331-3385 x713

2006-04-24  Mark Mitchell  <mark@codesourcery.com>

	PR c++/27292
	* typeck.c (decay_conversion): Don't adjust bitfield types.
	(perform_integral_promotions): Treat bitfield enums as enums, not
	as short integer types.
	* tree.c (rvalue): Convert bitfields to their correct types.

2006-04-24  Mark Mitchell  <mark@codesourcery.com>

	PR c++/27292
	* g++.dg/conversion/bitfield1.C: New test.
	* g++.dg/conversion/bitfield2.C: Likewise.
	* g++.dg/conversion/bitfield3.C: Likewise.

Index: gcc/cp/typeck.c
===================================================================
--- gcc/cp/typeck.c	(revision 113212)
+++ gcc/cp/typeck.c	(working copy)
@@ -1435,7 +1435,6 @@ tree
 decay_conversion (tree exp)
 {
   tree type;
-  tree bitfield_type;
   enum tree_code code;
 
   type = TREE_TYPE (exp);
@@ -1448,10 +1447,6 @@ decay_conversion (tree exp)
       return error_mark_node;
     }
 
-  bitfield_type = is_bitfield_expr_with_lowered_type (exp);
-  if (bitfield_type) 
-    exp = build_nop (bitfield_type, exp);
-
   exp = decl_constant_value (exp);
 
   /* build_c_cast puts on a NOP_EXPR to make the result not an lvalue.
@@ -1533,7 +1528,13 @@ perform_integral_promotions (tree expr)
   tree type;
   tree promoted_type;
 
-  type = TREE_TYPE (expr);
+  /* [conv.prom]
+
+     If the bitfield has an enumerated type, it is treated as any
+     other value of that type for promotion purposes.  */
+  type = is_bitfield_expr_with_lowered_type (expr);
+  if (!type || TREE_CODE (type) != ENUMERAL_TYPE)
+    type = TREE_TYPE (expr);
   gcc_assert (INTEGRAL_OR_ENUMERATION_TYPE_P (type));
   promoted_type = type_promotes_to (type);
   if (type != promoted_type)
Index: gcc/cp/tree.c
===================================================================
--- gcc/cp/tree.c	(revision 113212)
+++ gcc/cp/tree.c	(working copy)
@@ -371,7 +371,9 @@ rvalue (tree expr)
   tree type;
   if (real_lvalue_p (expr))
     {
-      type = TREE_TYPE (expr);
+      type = is_bitfield_expr_with_lowered_type (expr);
+      if (!type)
+	type = TREE_TYPE (expr);
       /* [basic.lval]
 	 
          Non-class rvalues always have cv-unqualified types.  */
Index: gcc/testsuite/g++.dg/conversion/bitfield1.C
===================================================================
--- gcc/testsuite/g++.dg/conversion/bitfield1.C	(revision 0)
+++ gcc/testsuite/g++.dg/conversion/bitfield1.C	(revision 0)
@@ -0,0 +1,17 @@
+// { dg-do run }
+// { dg-options "-w" }
+
+enum E { a, b = 1LL << 48 };
+ 
+struct S {
+  E e : 3;
+};
+
+S s;
+
+int main () {
+  if (sizeof (E) != sizeof (long long))
+    return 1;
+  if (sizeof (s.e + 3) != sizeof (long long))
+    return 2;
+}
Index: gcc/testsuite/g++.dg/conversion/bitfield2.C
===================================================================
--- gcc/testsuite/g++.dg/conversion/bitfield2.C	(revision 0)
+++ gcc/testsuite/g++.dg/conversion/bitfield2.C	(revision 0)
@@ -0,0 +1,11 @@
+// PR c++/27292
+
+struct A
+{
+  int i : 8;
+};
+
+bool foo(A a)
+{
+  return int(a.i);
+}
Index: gcc/testsuite/g++.dg/conversion/bitfield3.C
===================================================================
--- gcc/testsuite/g++.dg/conversion/bitfield3.C	(revision 0)
+++ gcc/testsuite/g++.dg/conversion/bitfield3.C	(revision 0)
@@ -0,0 +1,14 @@
+// PR c++/16376
+// { dg-do run }
+
+int main(void){
+  struct bits {
+    unsigned int ui3 : 3;
+  } bits;
+  int i = -1;   /* is a very large positive number as unsigned */
+
+  bits.ui3 = 1u;
+  if( bits.ui3 < i )
+    return 1;
+  return 0;
+}


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