mirror of
https://github.com/gcc-mirror/gcc.git
synced 2024-11-21 13:40:47 +00:00
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:
parent
a4b9dcad08
commit
d1522e8f63
@ -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.
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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)))
|
||||
{
|
||||
|
@ -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;
|
||||
}
|
||||
|
11
gcc/testsuite/g++.dg/overload/defarg9.C
Normal file
11
gcc/testsuite/g++.dg/overload/defarg9.C
Normal 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 "" }
|
Loading…
Reference in New Issue
Block a user