aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorMark Mitchell <mark@codesourcery.com>2006-04-25 03:33:38 +0000
committerMark Mitchell <mmitchel@gcc.gnu.org>2006-04-25 03:33:38 +0000
commitefe1ad468ee736651ab40f75ad8fb576ed7f8a70 (patch)
tree9cb7bd0eab657259542747a3841de9e35c66cd77 /gcc
parent9c9bd27b0b17a012e7db07af76c48144c28d6ddc (diff)
downloadgcc-efe1ad468ee736651ab40f75ad8fb576ed7f8a70.zip
gcc-efe1ad468ee736651ab40f75ad8fb576ed7f8a70.tar.gz
gcc-efe1ad468ee736651ab40f75ad8fb576ed7f8a70.tar.bz2
re PR c++/27292 (ICE on casts on bitfields)
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. PR c++/27292 * g++.dg/conversion/bitfield1.C: New test. * g++.dg/conversion/bitfield2.C: Likewise. * g++.dg/conversion/bitfield3.C: Likewise. From-SVN: r113240
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog8
-rw-r--r--gcc/cp/tree.c4
-rw-r--r--gcc/cp/typeck.c13
-rw-r--r--gcc/testsuite/ChangeLog7
-rw-r--r--gcc/testsuite/g++.dg/conversion/bitfield1.C17
-rw-r--r--gcc/testsuite/g++.dg/conversion/bitfield2.C11
-rw-r--r--gcc/testsuite/g++.dg/conversion/bitfield3.C14
7 files changed, 67 insertions, 7 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index fe48ced..494bdef 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,11 @@
+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 Volker Reichelt <reichelt@igpm.rwth-aachen.de>
PR c++/19963
diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c
index d58b5b3..a956205 100644
--- a/gcc/cp/tree.c
+++ b/gcc/cp/tree.c
@@ -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. */
diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c
index 7fc6cab..394a4ec 100644
--- a/gcc/cp/typeck.c
+++ b/gcc/cp/typeck.c
@@ -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)
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index e6096c1..abad315 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,10 @@
+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.
+
2006-04-24 Andrew Pinski <pinskia@gcc.gnu.org>
Richard Guenther <rguenther@suse.de>
diff --git a/gcc/testsuite/g++.dg/conversion/bitfield1.C b/gcc/testsuite/g++.dg/conversion/bitfield1.C
new file mode 100644
index 0000000..a660e79
--- /dev/null
+++ b/gcc/testsuite/g++.dg/conversion/bitfield1.C
@@ -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;
+}
diff --git a/gcc/testsuite/g++.dg/conversion/bitfield2.C b/gcc/testsuite/g++.dg/conversion/bitfield2.C
new file mode 100644
index 0000000..aa60d35
--- /dev/null
+++ b/gcc/testsuite/g++.dg/conversion/bitfield2.C
@@ -0,0 +1,11 @@
+// PR c++/27292
+
+struct A
+{
+ int i : 8;
+};
+
+bool foo(A a)
+{
+ return int(a.i);
+}
diff --git a/gcc/testsuite/g++.dg/conversion/bitfield3.C b/gcc/testsuite/g++.dg/conversion/bitfield3.C
new file mode 100644
index 0000000..a897bf59
--- /dev/null
+++ b/gcc/testsuite/g++.dg/conversion/bitfield3.C
@@ -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;
+}