aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2012-01-16 13:40:26 -0500
committerJason Merrill <jason@gcc.gnu.org>2012-01-16 13:40:26 -0500
commit645c7a55f8861f10f68f3e7fc2ce86fa57fb6b15 (patch)
treebe90f943f42680f1ae78dea27e6f3952bac5125d /gcc/cp
parentf434733449a2d46c3e003fd839bf94f47023c055 (diff)
downloadgcc-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/cp')
-rw-r--r--gcc/cp/ChangeLog5
-rw-r--r--gcc/cp/typeck.c36
2 files changed, 27 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