Tested x86_64-pc-linux-gnu, applying to trunk. -- 8< --
While looking at another patch I noticed that on a few tests we were doing nonsensical things like building a reference to a reference. Make sure we catch that sooner. But let's be friendly in can_convert, since it doesn't return a conversion that could be wrongly applied to a reference. gcc/cp/ChangeLog: * call.cc (implicit_conversion): Check that FROM isn't a reference if we also got an EXPR argument. (convert_like_internal): Check that EXPR isn't a reference. (can_convert_arg): convert_from_reference if needed. --- gcc/cp/call.cc | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/gcc/cp/call.cc b/gcc/cp/call.cc index 47a12512024..5dbaec983f6 100644 --- a/gcc/cp/call.cc +++ b/gcc/cp/call.cc @@ -2116,6 +2116,9 @@ implicit_conversion (tree to, tree from, tree expr, bool c_cast_p, } } + /* An argument should have gone through convert_from_reference. */ + gcc_checking_assert (!expr || !TYPE_REF_P (from)); + if (TYPE_REF_P (to)) conv = reference_binding (to, from, expr, c_cast_p, flags, complain); else @@ -8506,6 +8509,8 @@ convert_like_internal (conversion *convs, tree expr, tree fn, int argnum, if (convs->bad_p && !(complain & tf_error)) return error_mark_node; + gcc_checking_assert (!TYPE_REF_P (TREE_TYPE (expr))); + if (convs->bad_p && convs->kind != ck_user && convs->kind != ck_list @@ -13694,6 +13699,14 @@ can_convert_arg (tree to, tree from, tree arg, int flags, conversion. */ push_deferring_access_checks (dk_deferred); + /* Handle callers like check_local_shadow forgetting to + convert_from_reference. */ + if (TYPE_REF_P (from) && arg) + { + arg = convert_from_reference (arg); + from = TREE_TYPE (arg); + } + t = implicit_conversion (to, from, arg, /*c_cast_p=*/false, flags, complain); ok_p = (t && !t->bad_p); -- 2.47.1