aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2024-12-23 19:56:43 -0500
committerJason Merrill <jason@redhat.com>2025-01-08 16:35:43 -0500
commit325189c675017b73015aff250da14b68247b289f (patch)
tree19e85b97a01748c57232fca04a71c2079b93071d
parent72bb6fbbc56fe6a45058f4f6eac0ed6cc4f16473 (diff)
downloadgcc-325189c675017b73015aff250da14b68247b289f.zip
gcc-325189c675017b73015aff250da14b68247b289f.tar.gz
gcc-325189c675017b73015aff250da14b68247b289f.tar.bz2
c++: add ref checks in conversion code
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.
-rw-r--r--gcc/cp/call.cc13
1 files changed, 13 insertions, 0 deletions
diff --git a/gcc/cp/call.cc b/gcc/cp/call.cc
index 47a1251..5dbaec9 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);