aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp/class.c
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2014-10-11 21:42:31 -0400
committerJason Merrill <jason@gcc.gnu.org>2014-10-11 21:42:31 -0400
commitd1522e8f63167d81f6bd77c5d29ffdba2e6fbe86 (patch)
tree52a295c7a10b57d2b3007a653db61008c5031b70 /gcc/cp/class.c
parenta4b9dcad0837d3bc03843df6f96e6cb830550af6 (diff)
downloadgcc-d1522e8f63167d81f6bd77c5d29ffdba2e6fbe86.zip
gcc-d1522e8f63167d81f6bd77c5d29ffdba2e6fbe86.tar.gz
gcc-d1522e8f63167d81f6bd77c5d29ffdba2e6fbe86.tar.bz2
re PR c++/62115 (ICE with invalid default argument)
PR c++/62115 * class.c (build_base_path): Preserve rvalueness. * call.c (convert_like_real) [ck_base]: Let convert_to_base handle &/*. * rtti.c (build_dynamic_cast_1): Call convert_to_reference later. From-SVN: r216124
Diffstat (limited to 'gcc/cp/class.c')
-rw-r--r--gcc/cp/class.c25
1 files changed, 16 insertions, 9 deletions
diff --git a/gcc/cp/class.c b/gcc/cp/class.c
index b661187..99bfa95 100644
--- a/gcc/cp/class.c
+++ b/gcc/cp/class.c
@@ -251,6 +251,7 @@ build_base_path (enum tree_code code,
int want_pointer = TYPE_PTR_P (TREE_TYPE (expr));
bool has_empty = false;
bool virtual_access;
+ bool rvalue = false;
if (expr == error_mark_node || binfo == error_mark_node || !binfo)
return error_mark_node;
@@ -324,8 +325,11 @@ build_base_path (enum tree_code code,
}
if (!want_pointer)
- /* This must happen before the call to save_expr. */
- expr = cp_build_addr_expr (expr, complain);
+ {
+ rvalue = !real_lvalue_p (expr);
+ /* This must happen before the call to save_expr. */
+ expr = cp_build_addr_expr (expr, complain);
+ }
else
expr = mark_rvalue_use (expr);
@@ -351,9 +355,7 @@ build_base_path (enum tree_code code,
|| in_template_function ())
{
expr = build_nop (ptr_target_type, expr);
- if (!want_pointer)
- expr = build_indirect_ref (EXPR_LOCATION (expr), expr, RO_NULL);
- return expr;
+ goto indout;
}
/* If we're in an NSDMI, we don't have the full constructor context yet
@@ -364,9 +366,7 @@ build_base_path (enum tree_code code,
{
expr = build1 (CONVERT_EXPR, ptr_target_type, expr);
CONVERT_EXPR_VBASE_PATH (expr) = true;
- if (!want_pointer)
- expr = build_indirect_ref (EXPR_LOCATION (expr), expr, RO_NULL);
- return expr;
+ goto indout;
}
/* Do we need to check for a null pointer? */
@@ -402,6 +402,8 @@ build_base_path (enum tree_code code,
{
expr = cp_build_indirect_ref (expr, RO_NULL, complain);
expr = build_simple_base_path (expr, binfo);
+ if (rvalue)
+ expr = move (expr);
if (want_pointer)
expr = build_address (expr);
target_type = TREE_TYPE (expr);
@@ -478,8 +480,13 @@ build_base_path (enum tree_code code,
else
null_test = NULL;
+ indout:
if (!want_pointer)
- expr = cp_build_indirect_ref (expr, RO_NULL, complain);
+ {
+ expr = cp_build_indirect_ref (expr, RO_NULL, complain);
+ if (rvalue)
+ expr = move (expr);
+ }
out:
if (null_test)