Index: /trunk/src/wp-admin/edit-form-comment.php
===================================================================
--- /trunk/src/wp-admin/edit-form-comment.php	(revision 62825)
+++ /trunk/src/wp-admin/edit-form-comment.php	(revision 62826)
@@ -222,4 +222,7 @@
 	$max_thread_depth = (int) get_option( 'thread_comments_depth' );
 
+	// Pending comments may be nested under pending parents, but approved comments require publicly visible parents.
+	$parent_statuses = '1' === $comment->comment_approved ? 'approve' : array( 'approve', 'hold' );
+
 	// Limit the number of comments to keep memory usage and the size of the dropdown reasonable on busy posts.
 	$post_comments = get_comments(
@@ -227,5 +230,5 @@
 			'post_id' => $comment->comment_post_ID,
 			'type'    => 'comment',
-			'status'  => array( 'approve', 'hold' ),
+			'status'  => $parent_statuses,
 			'orderby' => 'comment_date_gmt',
 			'order'   => 'DESC',
Index: /trunk/src/wp-admin/includes/comment.php
===================================================================
--- /trunk/src/wp-admin/includes/comment.php	(revision 62825)
+++ /trunk/src/wp-admin/includes/comment.php	(revision 62826)
@@ -93,12 +93,16 @@
 			}
 
-			$parent = get_comment( $comment_parent );
-
-			// The parent must be a comment of the same type, on the same post, and not in the Trash or marked as spam.
+			$parent              = get_comment( $comment_parent );
+			$parent_status       = $parent ? wp_get_comment_status( $parent ) : false;
+			$comment_status      = $_POST['comment_approved'] ?? $comment->comment_approved;
+			$comment_is_approved = in_array( $comment_status, array( 1, '1', 'approve' ), true );
+
+			// The parent must be a comment of the same type, on the same post, and publicly visible if the comment is approved.
 			if (
 				! $parent
 				|| (int) $parent->comment_post_ID !== (int) $comment->comment_post_ID
 				|| $parent->comment_type !== $comment->comment_type
-				|| in_array( wp_get_comment_status( $parent ), array( 'spam', 'trash' ), true )
+				|| in_array( $parent_status, array( 'spam', 'trash' ), true )
+				|| ( $comment_is_approved && 'approved' !== $parent_status )
 			) {
 				return new WP_Error( 'comment_parent_invalid', __( 'Invalid parent comment.' ) );
Index: /trunk/tests/phpunit/tests/admin/EditFormComment_Test.php
===================================================================
--- /trunk/tests/phpunit/tests/admin/EditFormComment_Test.php	(revision 62825)
+++ /trunk/tests/phpunit/tests/admin/EditFormComment_Test.php	(revision 62826)
@@ -97,4 +97,10 @@
 			)
 		);
+		$pending_id = self::factory()->comment->create(
+			array(
+				'comment_post_ID'  => self::$post_id,
+				'comment_approved' => '0',
+			)
+		);
 		$comment_id = self::factory()->comment->create( array( 'comment_post_ID' => self::$post_id ) );
 		$child_id   = self::factory()->comment->create(
@@ -114,4 +120,27 @@
 		$this->assertStringNotContainsString( "value='{$spam_id}'", $dropdown, 'A spam comment should not be listed.' );
 		$this->assertStringNotContainsString( "value='{$trash_id}'", $dropdown, 'A trashed comment should not be listed.' );
+		$this->assertStringNotContainsString( "value='{$pending_id}'", $dropdown, 'A pending comment should not be listed for an approved comment.' );
+	}
+
+	/**
+	 * @ticket 65688
+	 */
+	public function test_should_list_pending_parent_for_pending_comment() {
+		$parent_id  = self::factory()->comment->create(
+			array(
+				'comment_post_ID'  => self::$post_id,
+				'comment_approved' => '0',
+			)
+		);
+		$comment_id = self::factory()->comment->create(
+			array(
+				'comment_post_ID'  => self::$post_id,
+				'comment_approved' => '0',
+			)
+		);
+
+		$dropdown = $this->get_parent_dropdown( $comment_id );
+
+		$this->assertStringContainsString( "value='{$parent_id}'", $dropdown, 'A pending comment should be listed for another pending comment.' );
 	}
 
Index: /trunk/tests/phpunit/tests/admin/includes/comment/EditComment_Test.php
===================================================================
--- /trunk/tests/phpunit/tests/admin/includes/comment/EditComment_Test.php	(revision 62825)
+++ /trunk/tests/phpunit/tests/admin/includes/comment/EditComment_Test.php	(revision 62826)
@@ -50,9 +50,10 @@
 	 * Calls edit_comment() with a comment ID and a new parent, as submitted from the Edit Comment screen.
 	 *
-	 * @param int $comment_id     Comment ID.
-	 * @param int $comment_parent New parent comment ID.
+	 * @param int         $comment_id     Comment ID.
+	 * @param int         $comment_parent New parent comment ID.
+	 * @param string|null $comment_status Optional. New comment status.
 	 * @return int|WP_Error The edit_comment() return value.
 	 */
-	private function update_comment_parent( $comment_id, $comment_parent ) {
+	private function update_comment_parent( $comment_id, $comment_parent, $comment_status = null ) {
 		$_POST = array(
 			'comment_ID'     => $comment_id,
@@ -60,4 +61,8 @@
 		);
 
+		if ( null !== $comment_status ) {
+			$_POST['comment_status'] = $comment_status;
+		}
+
 		return edit_comment();
 	}
@@ -73,4 +78,67 @@
 
 		$this->assertSame( 1, $result );
+		$this->assertSame( (string) $parent_id, get_comment( $comment_id )->comment_parent );
+	}
+
+	/**
+	 * @ticket 65688
+	 */
+	public function test_should_reject_unapproved_parent_for_approved_comment() {
+		$parent_id  = self::factory()->comment->create(
+			array(
+				'comment_post_ID'  => self::$post_id,
+				'comment_approved' => '0',
+			)
+		);
+		$comment_id = self::factory()->comment->create( array( 'comment_post_ID' => self::$post_id ) );
+
+		$result = $this->update_comment_parent( $comment_id, $parent_id );
+
+		$this->assertWPError( $result );
+		$this->assertSame( 'comment_parent_invalid', $result->get_error_code() );
+		$this->assertSame( '0', get_comment( $comment_id )->comment_parent );
+	}
+
+	/**
+	 * @ticket 65688
+	 */
+	public function test_should_reject_unapproved_parent_when_comment_is_approved_in_same_update() {
+		$parent_id  = self::factory()->comment->create(
+			array(
+				'comment_post_ID'  => self::$post_id,
+				'comment_approved' => '0',
+			)
+		);
+		$comment_id = self::factory()->comment->create(
+			array(
+				'comment_post_ID'  => self::$post_id,
+				'comment_approved' => '0',
+			)
+		);
+
+		$result = $this->update_comment_parent( $comment_id, $parent_id, '1' );
+
+		$this->assertWPError( $result );
+		$this->assertSame( 'comment_parent_invalid', $result->get_error_code() );
+		$this->assertSame( '0', get_comment( $comment_id )->comment_approved );
+		$this->assertSame( '0', get_comment( $comment_id )->comment_parent );
+	}
+
+	/**
+	 * @ticket 65688
+	 */
+	public function test_should_allow_unapproved_parent_when_comment_is_unapproved_in_same_update() {
+		$parent_id  = self::factory()->comment->create(
+			array(
+				'comment_post_ID'  => self::$post_id,
+				'comment_approved' => '0',
+			)
+		);
+		$comment_id = self::factory()->comment->create( array( 'comment_post_ID' => self::$post_id ) );
+
+		$result = $this->update_comment_parent( $comment_id, $parent_id, '0' );
+
+		$this->assertSame( 1, $result );
+		$this->assertSame( '0', get_comment( $comment_id )->comment_approved );
 		$this->assertSame( (string) $parent_id, get_comment( $comment_id )->comment_parent );
 	}
