diff options
author | Mark Mitchell <mark@codesourcery.com> | 2006-04-25 03:33:38 +0000 |
---|---|---|
committer | Mark Mitchell <mmitchel@gcc.gnu.org> | 2006-04-25 03:33:38 +0000 |
commit | efe1ad468ee736651ab40f75ad8fb576ed7f8a70 (patch) | |
tree | 9cb7bd0eab657259542747a3841de9e35c66cd77 /gcc | |
parent | 9c9bd27b0b17a012e7db07af76c48144c28d6ddc (diff) | |
download | gcc-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/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/cp/tree.c | 4 | ||||
-rw-r--r-- | gcc/cp/typeck.c | 13 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/conversion/bitfield1.C | 17 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/conversion/bitfield2.C | 11 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/conversion/bitfield3.C | 14 |
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; +} |