From: Jason Merrill Date: Mon, 16 Jan 2012 21:34:26 +0000 (-0500) Subject: re PR c++/51868 (Crash when generating the move constructor for a class with a bit... X-Git-Tag: releases/gcc-4.6.3~173 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=4bfb5b076cc4689e954f2426780b359edf234275;p=thirdparty%2Fgcc.git re PR c++/51868 (Crash when generating the move constructor for a class with a bit field) PR c++/51868 * typeck.c (build_static_cast_1): Handle bit-fields properly. From-SVN: r183223 --- diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 9bb036625521..f302fc3b353b 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. + 2011-12-20 Dodji Seketeli PR debug/49951 diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index 1c099a2c80ca..deb895111b62 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -5696,11 +5696,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); @@ -5766,22 +5767,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 ec2fc42f69d4..5c13ce27f026 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-15 Uros Bizjak PR rtl-optimization/51821 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 000000000000..ed866f9e1f37 --- /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 000000000000..e054151b056b --- /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(); +}