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
This commit is contained in:
Jason Merrill 2014-10-11 21:42:31 -04:00 committed by Jason Merrill
parent a4b9dcad08
commit d1522e8f63
6 changed files with 41 additions and 17 deletions

View File

@ -1,5 +1,10 @@
2014-10-10 Jason Merrill <jason@redhat.com>
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.
PR c++/63194
* method.c (defaulted_late_check): Call maybe_instantiate_noexcept.

View File

@ -6341,10 +6341,8 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum,
/* We are going to bind a reference directly to a base-class
subobject of EXPR. */
/* Build an expression for `*((base*) &expr)'. */
expr = cp_build_addr_expr (expr, complain);
expr = convert_to_base (expr, build_pointer_type (totype),
expr = convert_to_base (expr, totype,
!c_cast_p, /*nonnull=*/true, complain);
expr = cp_build_indirect_ref (expr, RO_IMPLICIT_CONVERSION, complain);
return expr;
}

View File

@ -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)

View File

@ -608,10 +608,6 @@ build_dynamic_cast_1 (tree type, tree expr, tsubst_flags_t complain)
errstr = _("source is of incomplete class type");
goto fail;
}
/* Apply trivial conversion T -> T& for dereferenced ptrs. */
expr = convert_to_reference (exprtype, expr, CONV_IMPLICIT,
LOOKUP_NORMAL, NULL_TREE, complain);
}
/* The dynamic_cast operator shall not cast away constness. */
@ -631,6 +627,11 @@ build_dynamic_cast_1 (tree type, tree expr, tsubst_flags_t complain)
return build_static_cast (type, expr, complain);
}
/* Apply trivial conversion T -> T& for dereferenced ptrs. */
if (tc == REFERENCE_TYPE)
expr = convert_to_reference (exprtype, expr, CONV_IMPLICIT,
LOOKUP_NORMAL, NULL_TREE, complain);
/* Otherwise *exprtype must be a polymorphic class (have a vtbl). */
if (TYPE_POLYMORPHIC_P (TREE_TYPE (exprtype)))
{

View File

@ -1,10 +1,11 @@
// { dg-do run }
extern "C" void abort ();
bool ok = false;
struct B {
B() {}
B(const B& b) { abort (); }
B(const B& b) { ok = true; }
};
struct D : public B {
@ -21,4 +22,5 @@ D f() {
int main () {
b = (true ? f() : b);
return !ok;
}

View File

@ -0,0 +1,11 @@
// PR c++/62115
struct A {};
struct B : A {};
struct C
{
C(A& a = B()) {} // { dg-error "rvalue" }
};
C c; // { dg-error "" }