diff --git a/src/backend/utils/adt/arrayfuncs.c b/src/backend/utils/adt/arrayfuncs.c
index 4c8a739bc4..15cb3b312f 100644
--- a/src/backend/utils/adt/arrayfuncs.c
+++ b/src/backend/utils/adt/arrayfuncs.c
@@ -2583,7 +2583,9 @@ array_set_element_expanded(Datum arraydatum,
 	/*
 	 * Copy new element into array's context, if needed (we assume it's
 	 * already detoasted, so no junk should be created).  If we fail further
-	 * down, this memory is leaked, but that's reasonably harmless.
+	 * down, this memory is leaked, but that's reasonably harmless.  Note in
+	 * particular that doing this early ensures sanity in case the source
+	 * Datum is a pointer to a pass-by-ref element of this same array.
 	 */
 	if (!eah->typbyval && !isNull)
 	{
diff --git a/src/pl/plpgsql/src/pl_exec.c b/src/pl/plpgsql/src/pl_exec.c
index 5c1db1dcfb..1378f40d4d 100644
--- a/src/pl/plpgsql/src/pl_exec.c
+++ b/src/pl/plpgsql/src/pl_exec.c
@@ -8181,14 +8181,7 @@ exec_check_rw_parameter(PLpgSQL_expr *expr, int target_dno)
 			contains_target_param((Node *) sbsref->refexpr, &target_dno))
 			return;
 
-		/* the other subexpressions must not contain target */
-		if (contains_target_param((Node *) sbsref->refupperindexpr,
-								  &target_dno) ||
-			contains_target_param((Node *) sbsref->reflowerindexpr,
-								  &target_dno) ||
-			contains_target_param((Node *) sbsref->refassgnexpr,
-								  &target_dno))
-			return;
+		/* we do *not* need to restrict the subscripts or source expression */
 
 		/* OK, we can pass target as a read-write parameter */
 		expr->rwparam = target_dno;
