diff options
author | Jason Merrill <jason@redhat.com> | 2012-01-16 13:40:26 -0500 |
---|---|---|
committer | Jason Merrill <jason@gcc.gnu.org> | 2012-01-16 13:40:26 -0500 |
commit | 645c7a55f8861f10f68f3e7fc2ce86fa57fb6b15 (patch) | |
tree | be90f943f42680f1ae78dea27e6f3952bac5125d /gcc | |
parent | f434733449a2d46c3e003fd839bf94f47023c055 (diff) | |
download | gcc-645c7a55f8861f10f68f3e7fc2ce86fa57fb6b15.zip gcc-645c7a55f8861f10f68f3e7fc2ce86fa57fb6b15.tar.gz gcc-645c7a55f8861f10f68f3e7fc2ce86fa57fb6b15.tar.bz2 |
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: r183218
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/cp/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/cp/typeck.c | 36 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp0x/rv-bitfield.C | 12 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp0x/rv-bitfield2.C | 17 |
5 files changed, 62 insertions, 14 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 86ab82f..a5a07e4 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,8 @@ +2012-01-16 Jason Merrill <jason@redhat.com> + + PR c++/51868 + * typeck.c (build_static_cast_1): Handle bit-fields properly. + 2012-01-13 Ian Lance Taylor <iant@google.com> PR c++/50012 diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index 11edeee..91e7a0a 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 4e58ca5..0bdffcc 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2012-01-16 Jason Merrill <jason@redhat.com> + + PR c++/51868 + * g++.dg/cpp0x/rv-bitfield.C: New. + * g++.dg/cpp0x/rv-bitfield2.C: New. + 2012-01-16 Paul Thomas <pault@gcc.gnu.org> * 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 0000000..ed866f9 --- /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<int&&>(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 0000000..e054151 --- /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(); +} |