From 899e921132179b449ff760520984f37993901ca0 Mon Sep 17 00:00:00 2001 From: jason Date: Mon, 16 Jan 2012 18:40:26 +0000 Subject: [PATCH] PR c++/51868 * typeck.c (build_static_cast_1): Handle bit-fields properly. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@183218 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/cp/ChangeLog | 5 +++++ gcc/cp/typeck.c | 36 +++++++++++++++++++------------ gcc/testsuite/ChangeLog | 6 ++++++ gcc/testsuite/g++.dg/cpp0x/rv-bitfield.C | 12 +++++++++++ gcc/testsuite/g++.dg/cpp0x/rv-bitfield2.C | 17 +++++++++++++++ 5 files changed, 62 insertions(+), 14 deletions(-) create mode 100644 gcc/testsuite/g++.dg/cpp0x/rv-bitfield.C create mode 100644 gcc/testsuite/g++.dg/cpp0x/rv-bitfield2.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 86ab82f985a..a5a07e47db8 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,8 @@ +2012-01-16 Jason Merrill + + PR c++/51868 + * typeck.c (build_static_cast_1): Handle bit-fields properly. + 2012-01-13 Ian Lance Taylor PR c++/50012 diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index 11edeeed3b9..91e7a0a09ca 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -5812,11 +5812,12 @@ build_static_cast_1 (tree type, tree expr, bool c_cast_p, { tree intype; tree result; + cp_lvalue_kind clk; /* Assume the cast is valid. */ *valid_p = true; - intype = TREE_TYPE (expr); + intype = unlowered_expr_type (expr); /* Save casted types in the function's used types hash table. */ used_types_insert (type); @@ -5882,22 +5883,29 @@ build_static_cast_1 (tree type, tree expr, bool c_cast_p, cv2 T2 if cv2 T2 is reference-compatible with cv1 T1 (8.5.3)." */ if (TREE_CODE (type) == REFERENCE_TYPE && TYPE_REF_IS_RVALUE (type) - && real_lvalue_p (expr) + && (clk = real_lvalue_p (expr)) && reference_related_p (TREE_TYPE (type), intype) && (c_cast_p || at_least_as_qualified_p (TREE_TYPE (type), intype))) { - /* Handle the lvalue case here by casting to lvalue reference and - then changing it to an rvalue reference. Casting an xvalue to - rvalue reference will be handled by the main code path. */ - tree lref = cp_build_reference_type (TREE_TYPE (type), false); - result = (perform_direct_initialization_if_possible - (lref, expr, c_cast_p, complain)); - result = cp_fold_convert (type, result); - /* Make sure we don't fold back down to a named rvalue reference, - because that would be an lvalue. */ - if (DECL_P (result)) - result = build1 (NON_LVALUE_EXPR, type, result); - return convert_from_reference (result); + if (clk == clk_ordinary) + { + /* Handle the (non-bit-field) lvalue case here by casting to + lvalue reference and then changing it to an rvalue reference. + Casting an xvalue to rvalue reference will be handled by the + main code path. */ + tree lref = cp_build_reference_type (TREE_TYPE (type), false); + result = (perform_direct_initialization_if_possible + (lref, expr, c_cast_p, complain)); + result = cp_fold_convert (type, result); + /* Make sure we don't fold back down to a named rvalue reference, + because that would be an lvalue. */ + if (DECL_P (result)) + result = build1 (NON_LVALUE_EXPR, type, result); + return convert_from_reference (result); + } + else + /* For a bit-field or packed field, bind to a temporary. */ + expr = rvalue (expr); } /* Resolve overloaded address here rather than once in diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 4e58ca5c018..0bdffcc3761 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2012-01-16 Jason Merrill + + PR c++/51868 + * g++.dg/cpp0x/rv-bitfield.C: New. + * g++.dg/cpp0x/rv-bitfield2.C: New. + 2012-01-16 Paul Thomas * gfortran.dg/class_array_3.f03: Remove the explicit loop in diff --git a/gcc/testsuite/g++.dg/cpp0x/rv-bitfield.C b/gcc/testsuite/g++.dg/cpp0x/rv-bitfield.C new file mode 100644 index 00000000000..ed866f9e1f3 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/rv-bitfield.C @@ -0,0 +1,12 @@ +// { dg-options -std=c++0x } + +struct A +{ + int i : 1; +}; + +int main() +{ + A a; + static_cast(a.i); +} diff --git a/gcc/testsuite/g++.dg/cpp0x/rv-bitfield2.C b/gcc/testsuite/g++.dg/cpp0x/rv-bitfield2.C new file mode 100644 index 00000000000..e054151b056 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/rv-bitfield2.C @@ -0,0 +1,17 @@ +// PR c++/51868 +// { dg-options -std=c++0x } + +struct A { + A() {} + A(const A&) {} + A(A&&) {} +}; + +struct B { + A a; + int f : 1; +}; + +B func() { + return B(); +} -- 2.11.4.GIT