From 661c81f5a36317e31464612bb17af55448ceba09 Mon Sep 17 00:00:00 2001 From: mmitchel Date: Tue, 25 Apr 2006 03:33:38 +0000 Subject: [PATCH] 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@113240 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/cp/ChangeLog | 8 ++++++++ gcc/cp/tree.c | 4 +++- gcc/cp/typeck.c | 13 +++++++------ gcc/testsuite/ChangeLog | 7 +++++++ gcc/testsuite/g++.dg/conversion/bitfield1.C | 17 +++++++++++++++++ gcc/testsuite/g++.dg/conversion/bitfield2.C | 11 +++++++++++ gcc/testsuite/g++.dg/conversion/bitfield3.C | 14 ++++++++++++++ 7 files changed, 67 insertions(+), 7 deletions(-) create mode 100644 gcc/testsuite/g++.dg/conversion/bitfield1.C create mode 100644 gcc/testsuite/g++.dg/conversion/bitfield2.C create mode 100644 gcc/testsuite/g++.dg/conversion/bitfield3.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index fe48ced0532..494bdef22c6 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,11 @@ +2006-04-24 Mark Mitchell + + 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 PR c++/19963 diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c index d58b5b350dd..a956205a136 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 7fc6cab7aea..394a4ec0575 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 e6096c11bfe..abad315a6c2 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,10 @@ +2006-04-24 Mark Mitchell + + 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 Richard Guenther diff --git a/gcc/testsuite/g++.dg/conversion/bitfield1.C b/gcc/testsuite/g++.dg/conversion/bitfield1.C new file mode 100644 index 00000000000..a660e79503d --- /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 00000000000..aa60d350578 --- /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 00000000000..a897bf59e5d --- /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; +} -- 2.11.4.GIT