diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index a7f15694c34b..66d42cc41f84 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -1301,7 +1301,8 @@ C_COMMON_OBJS = c-family/c-common.o c-family/c-cppbuiltin.o c-family/c-dump.o \
   c-family/c-ppoutput.o c-family/c-pragma.o c-family/c-pretty-print.o \
   c-family/c-semantics.o c-family/c-ada-spec.o \
   c-family/c-ubsan.o c-family/known-headers.o \
-  c-family/c-attribs.o c-family/c-warn.o c-family/c-spellcheck.o
+  c-family/c-attribs.o c-family/c-warn.o c-family/c-spellcheck.o \
+  c-family/c-type-mismatch.o
 
 # Analyzer object files
 ANALYZER_OBJS = \
diff --git a/gcc/c-family/c-format.cc b/gcc/c-family/c-format.cc
index 9c4deabc1095..7a5ffc25602c 100644
--- a/gcc/c-family/c-format.cc
+++ b/gcc/c-family/c-format.cc
@@ -35,7 +35,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "selftest-diagnostic.h"
 #include "builtins.h"
 #include "attribs.h"
-#include "gcc-rich-location.h"
+#include "c-family/c-type-mismatch.h"
 
 /* Handle attributes associated with format checking.  */
 
diff --git a/gcc/c-family/c-type-mismatch.cc b/gcc/c-family/c-type-mismatch.cc
new file mode 100644
index 000000000000..fae31261d544
--- /dev/null
+++ b/gcc/c-family/c-type-mismatch.cc
@@ -0,0 +1,127 @@
+/* Implementations of classes for reporting type mismatches.
+   Copyright (C) 2014-2024 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 3, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3.  If not see
+<http://www.gnu.org/licenses/>.  */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "hash-set.h"
+#include "vec.h"
+#include "input.h"
+#include "alias.h"
+#include "symtab.h"
+#include "inchash.h"
+#include "tree-core.h"
+#include "tree.h"
+#include "diagnostic-core.h"
+#include "c-family/c-type-mismatch.h"
+#include "print-tree.h"
+#include "pretty-print.h"
+#include "intl.h"
+#include "cpplib.h"
+#include "diagnostic.h"
+
+/* Implementation of range_label::get_text for
+   maybe_range_label_for_tree_type_mismatch.
+
+   If both expressions are non-NULL, then generate text describing
+   the first expression's type (using the other expression's type
+   for comparison, analogous to %H and %I in the C++ frontend, but
+   on expressions rather than types).  */
+
+label_text
+maybe_range_label_for_tree_type_mismatch::get_text (unsigned range_idx) const
+{
+  if (m_expr == NULL_TREE
+      || !EXPR_P (m_expr))
+    return label_text::borrow (NULL);
+  tree expr_type = TREE_TYPE (m_expr);
+
+  tree other_type = NULL_TREE;
+  if (m_other_expr && EXPR_P (m_other_expr))
+    other_type = TREE_TYPE (m_other_expr);
+
+  range_label_for_type_mismatch inner (expr_type, other_type);
+  return inner.get_text (range_idx);
+}
+
+/* binary_op_rich_location's ctor.
+
+   If use_operator_loc_p (LOC, ARG0, ARG1), then attempt to make a 3-location
+   rich_location of the form:
+
+     arg_0 op arg_1
+     ~~~~~ ^~ ~~~~~
+       |        |
+       |        arg1 type
+       arg0 type
+
+   labelling the types of the arguments if SHOW_TYPES is true.
+
+   Otherwise, make a 1-location rich_location using the compound
+   location within LOC:
+
+     arg_0 op arg_1
+     ~~~~~~^~~~~~~~
+
+   for which we can't label the types.  */
+
+binary_op_rich_location::binary_op_rich_location (const op_location_t &loc,
+						  tree arg0, tree arg1,
+						  bool show_types)
+: gcc_rich_location (loc.m_combined_loc),
+  m_label_for_arg0 (arg0, arg1),
+  m_label_for_arg1 (arg1, arg0)
+{
+  /* Default (above) to using the combined loc.
+     Potentially override it here: if we have location information for the
+     operator and for both arguments, then split them all out.
+     Alternatively, override it if we don't have the combined location.  */
+  if (use_operator_loc_p (loc, arg0, arg1))
+    {
+      set_range (0, loc.m_operator_loc, SHOW_RANGE_WITH_CARET);
+      maybe_add_expr (arg0, show_types ? &m_label_for_arg0 : NULL);
+      maybe_add_expr (arg1, show_types ? &m_label_for_arg1 : NULL);
+    }
+}
+
+/* Determine if binary_op_rich_location's ctor should attempt to make
+   a 3-location rich_location (the location of the operator and of
+   the 2 arguments), or fall back to a 1-location rich_location showing
+   just the combined location of the operation as a whole.  */
+
+bool
+binary_op_rich_location::use_operator_loc_p (const op_location_t &loc,
+					     tree arg0, tree arg1)
+{
+  /* If we don't have a combined location, then use the operator location,
+     and try to add ranges for the operators.  */
+  if (loc.m_combined_loc == UNKNOWN_LOCATION)
+    return true;
+
+  /* If we don't have the operator location, then use the
+     combined location.  */
+  if (loc.m_operator_loc == UNKNOWN_LOCATION)
+    return false;
+
+  /* We have both operator location and combined location: only use the
+     operator location if we have locations for both arguments.  */
+  return (EXPR_HAS_LOCATION (arg0)
+	  && EXPR_HAS_LOCATION (arg1));
+}
diff --git a/gcc/c-family/c-type-mismatch.h b/gcc/c-family/c-type-mismatch.h
new file mode 100644
index 000000000000..58fba5d4d6ee
--- /dev/null
+++ b/gcc/c-family/c-type-mismatch.h
@@ -0,0 +1,126 @@
+/* Declarations relating to classes for reporting type mismatches.
+   Copyright (C) 2014-2024 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 3, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3.  If not see
+<http://www.gnu.org/licenses/>.  */
+
+#ifndef GCC_C_TYPE_MISMATCH_H
+#define GCC_C_TYPE_MISMATCH_H
+
+#include "gcc-rich-location.h"
+
+/* Concrete subclass of libcpp's range_label for use in
+   diagnostics involving mismatched types.
+
+   Each frontend that uses this should supply its own implementation.
+
+   Generate a label describing LABELLED_TYPE.  The frontend may use
+   OTHER_TYPE where appropriate for highlighting the differences between
+   the two types (analogous to C++'s use of %H and %I with
+   template types).
+
+   Either or both of LABELLED_TYPE and OTHER_TYPE may be NULL_TREE.
+   If LABELLED_TYPE is NULL_TREE, then there is no label.
+
+   For example, this rich_location could use two instances of
+   range_label_for_type_mismatch:
+
+      printf ("arg0: %i  arg1: %s arg2: %i",
+                               ^~
+                               |
+                               const char *
+              100, 101, 102);
+                   ~~~
+                   |
+                   int
+
+   (a) the label for "%s" with LABELLED_TYPE for "const char*" and
+   (b) the label for "101" with LABELLED TYPE for "int"
+   where each one uses the other's type as OTHER_TYPE.  */
+
+class range_label_for_type_mismatch : public range_label
+{
+ public:
+  range_label_for_type_mismatch (tree labelled_type, tree other_type)
+  : m_labelled_type (labelled_type), m_other_type (other_type)
+  {
+  }
+
+  label_text get_text (unsigned range_idx) const override;
+
+ protected:
+  tree m_labelled_type;
+  tree m_other_type;
+};
+
+/* Subclass of range_label for labelling the type of EXPR when reporting
+   a type mismatch between EXPR and OTHER_EXPR.
+   Either or both of EXPR and OTHER_EXPR could be NULL.  */
+
+class maybe_range_label_for_tree_type_mismatch : public range_label
+{
+ public:
+  maybe_range_label_for_tree_type_mismatch (tree expr, tree other_expr)
+  : m_expr (expr), m_other_expr (other_expr)
+  {
+  }
+
+  label_text get_text (unsigned range_idx) const final override;
+
+ private:
+  tree m_expr;
+  tree m_other_expr;
+};
+
+class op_location_t;
+
+/* A subclass of rich_location for showing problems with binary operations.
+
+   If enough location information is available, the ctor will make a
+   3-location rich_location of the form:
+
+     arg_0 op arg_1
+     ~~~~~ ^~ ~~~~~
+       |        |
+       |        arg1 type
+       arg0 type
+
+   labelling the types of the arguments if SHOW_TYPES is true.
+
+   Otherwise, it will fall back to a 1-location rich_location using the
+   compound location within LOC:
+
+     arg_0 op arg_1
+     ~~~~~~^~~~~~~~
+
+   for which we can't label the types.  */
+
+class binary_op_rich_location : public gcc_rich_location
+{
+ public:
+  binary_op_rich_location (const op_location_t &loc,
+			   tree arg0, tree arg1,
+			   bool show_types);
+
+ private:
+  static bool use_operator_loc_p (const op_location_t &loc,
+				  tree arg0, tree arg1);
+
+  maybe_range_label_for_tree_type_mismatch m_label_for_arg0;
+  maybe_range_label_for_tree_type_mismatch m_label_for_arg1;
+};
+
+#endif /* GCC_C_TYPE_MISMATCH_H */
diff --git a/gcc/c-family/c-warn.cc b/gcc/c-family/c-warn.cc
index 5b2d6805c790..7ddf6ea2ad8e 100644
--- a/gcc/c-family/c-warn.cc
+++ b/gcc/c-family/c-warn.cc
@@ -32,7 +32,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "stringpool.h"
 #include "attribs.h"
 #include "asan.h"
-#include "gcc-rich-location.h"
+#include "c-family/c-type-mismatch.h"
 #include "gimplify.h"
 #include "c-family/c-indentation.h"
 #include "c-family/c-spellcheck.h"
diff --git a/gcc/c/c-objc-common.cc b/gcc/c/c-objc-common.cc
index b7c72d2609c6..42a62c84fe7c 100644
--- a/gcc/c/c-objc-common.cc
+++ b/gcc/c/c-objc-common.cc
@@ -27,7 +27,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "gimple-pretty-print.h"
 #include "langhooks.h"
 #include "c-objc-common.h"
-#include "gcc-rich-location.h"
+#include "c-family/c-type-mismatch.h"
 #include "stringpool.h"
 #include "attribs.h"
 #include "dwarf2.h"
diff --git a/gcc/c/c-typeck.cc b/gcc/c/c-typeck.cc
index 7ecca9f58c68..7195adc0604e 100644
--- a/gcc/c/c-typeck.cc
+++ b/gcc/c/c-typeck.cc
@@ -48,7 +48,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "c-family/c-ubsan.h"
 #include "gomp-constants.h"
 #include "spellcheck-tree.h"
-#include "gcc-rich-location.h"
+#include "c-family/c-type-mismatch.h"
 #include "stringpool.h"
 #include "attribs.h"
 #include "asan.h"
diff --git a/gcc/cp/call.cc b/gcc/cp/call.cc
index ed68eb3c5684..886760af699f 100644
--- a/gcc/cp/call.cc
+++ b/gcc/cp/call.cc
@@ -42,7 +42,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "stringpool.h"
 #include "attribs.h"
 #include "decl.h"
-#include "gcc-rich-location.h"
+#include "c-family/c-type-mismatch.h"
 #include "tristate.h"
 
 /* The various kinds of conversion.  */
diff --git a/gcc/cp/error.cc b/gcc/cp/error.cc
index 37987ccb570d..0ff7f9d4c468 100644
--- a/gcc/cp/error.cc
+++ b/gcc/cp/error.cc
@@ -34,7 +34,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "c-family/c-objc.h"
 #include "ubsan.h"
 #include "internal-fn.h"
-#include "gcc-rich-location.h"
+#include "c-family/c-type-mismatch.h"
 #include "cp-name-hint.h"
 #include "attribs.h"
 
diff --git a/gcc/cp/typeck.cc b/gcc/cp/typeck.cc
index 5f16994300fd..8f751d546139 100644
--- a/gcc/cp/typeck.cc
+++ b/gcc/cp/typeck.cc
@@ -35,7 +35,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "convert.h"
 #include "c-family/c-objc.h"
 #include "c-family/c-ubsan.h"
-#include "gcc-rich-location.h"
+#include "c-family/c-type-mismatch.h"
 #include "stringpool.h"
 #include "attribs.h"
 #include "asan.h"
diff --git a/gcc/gcc-rich-location.cc b/gcc/gcc-rich-location.cc
index f83ba754ba42..e9d753badfe0 100644
--- a/gcc/gcc-rich-location.cc
+++ b/gcc/gcc-rich-location.cc
@@ -185,92 +185,3 @@ gcc_rich_location::add_fixit_insert_formatted (const char *content,
   else
     add_fixit_insert_before (insertion_point, content);
 }
-
-/* Implementation of range_label::get_text for
-   maybe_range_label_for_tree_type_mismatch.
-
-   If both expressions are non-NULL, then generate text describing
-   the first expression's type (using the other expression's type
-   for comparison, analogous to %H and %I in the C++ frontend, but
-   on expressions rather than types).  */
-
-label_text
-maybe_range_label_for_tree_type_mismatch::get_text (unsigned range_idx) const
-{
-  if (m_expr == NULL_TREE
-      || !EXPR_P (m_expr))
-    return label_text::borrow (NULL);
-  tree expr_type = TREE_TYPE (m_expr);
-
-  tree other_type = NULL_TREE;
-  if (m_other_expr && EXPR_P (m_other_expr))
-    other_type = TREE_TYPE (m_other_expr);
-
-  range_label_for_type_mismatch inner (expr_type, other_type);
-  return inner.get_text (range_idx);
-}
-
-/* binary_op_rich_location's ctor.
-
-   If use_operator_loc_p (LOC, ARG0, ARG1), then attempt to make a 3-location
-   rich_location of the form:
-
-     arg_0 op arg_1
-     ~~~~~ ^~ ~~~~~
-       |        |
-       |        arg1 type
-       arg0 type
-
-   labelling the types of the arguments if SHOW_TYPES is true.
-
-   Otherwise, make a 1-location rich_location using the compound
-   location within LOC:
-
-     arg_0 op arg_1
-     ~~~~~~^~~~~~~~
-
-   for which we can't label the types.  */
-
-binary_op_rich_location::binary_op_rich_location (const op_location_t &loc,
-						  tree arg0, tree arg1,
-						  bool show_types)
-: gcc_rich_location (loc.m_combined_loc),
-  m_label_for_arg0 (arg0, arg1),
-  m_label_for_arg1 (arg1, arg0)
-{
-  /* Default (above) to using the combined loc.
-     Potentially override it here: if we have location information for the
-     operator and for both arguments, then split them all out.
-     Alternatively, override it if we don't have the combined location.  */
-  if (use_operator_loc_p (loc, arg0, arg1))
-    {
-      set_range (0, loc.m_operator_loc, SHOW_RANGE_WITH_CARET);
-      maybe_add_expr (arg0, show_types ? &m_label_for_arg0 : NULL);
-      maybe_add_expr (arg1, show_types ? &m_label_for_arg1 : NULL);
-    }
-}
-
-/* Determine if binary_op_rich_location's ctor should attempt to make
-   a 3-location rich_location (the location of the operator and of
-   the 2 arguments), or fall back to a 1-location rich_location showing
-   just the combined location of the operation as a whole.  */
-
-bool
-binary_op_rich_location::use_operator_loc_p (const op_location_t &loc,
-					     tree arg0, tree arg1)
-{
-  /* If we don't have a combined location, then use the operator location,
-     and try to add ranges for the operators.  */
-  if (loc.m_combined_loc == UNKNOWN_LOCATION)
-    return true;
-
-  /* If we don't have the operator location, then use the
-     combined location.  */
-  if (loc.m_operator_loc == UNKNOWN_LOCATION)
-    return false;
-
-  /* We have both operator location and combined location: only use the
-     operator location if we have locations for both arguments.  */
-  return (EXPR_HAS_LOCATION (arg0)
-	  && EXPR_HAS_LOCATION (arg1));
-}
diff --git a/gcc/gcc-rich-location.h b/gcc/gcc-rich-location.h
index 3741b2d2cb23..5664cb95f029 100644
--- a/gcc/gcc-rich-location.h
+++ b/gcc/gcc-rich-location.h
@@ -124,105 +124,4 @@ class text_range_label : public range_label
   const char *m_text;
 };
 
-/* Concrete subclass of libcpp's range_label for use in
-   diagnostics involving mismatched types.
-
-   Each frontend that uses this should supply its own implementation.
-
-   Generate a label describing LABELLED_TYPE.  The frontend may use
-   OTHER_TYPE where appropriate for highlighting the differences between
-   the two types (analogous to C++'s use of %H and %I with
-   template types).
-
-   Either or both of LABELLED_TYPE and OTHER_TYPE may be NULL_TREE.
-   If LABELLED_TYPE is NULL_TREE, then there is no label.
-
-   For example, this rich_location could use two instances of
-   range_label_for_type_mismatch:
-
-      printf ("arg0: %i  arg1: %s arg2: %i",
-                               ^~
-                               |
-                               const char *
-              100, 101, 102);
-                   ~~~
-                   |
-                   int
-
-   (a) the label for "%s" with LABELLED_TYPE for "const char*" and
-   (b) the label for "101" with LABELLED TYPE for "int"
-   where each one uses the other's type as OTHER_TYPE.  */
-
-class range_label_for_type_mismatch : public range_label
-{
- public:
-  range_label_for_type_mismatch (tree labelled_type, tree other_type)
-  : m_labelled_type (labelled_type), m_other_type (other_type)
-  {
-  }
-
-  label_text get_text (unsigned range_idx) const override;
-
- protected:
-  tree m_labelled_type;
-  tree m_other_type;
-};
-
-/* Subclass of range_label for labelling the type of EXPR when reporting
-   a type mismatch between EXPR and OTHER_EXPR.
-   Either or both of EXPR and OTHER_EXPR could be NULL.  */
-
-class maybe_range_label_for_tree_type_mismatch : public range_label
-{
- public:
-  maybe_range_label_for_tree_type_mismatch (tree expr, tree other_expr)
-  : m_expr (expr), m_other_expr (other_expr)
-  {
-  }
-
-  label_text get_text (unsigned range_idx) const final override;
-
- private:
-  tree m_expr;
-  tree m_other_expr;
-};
-
-class op_location_t;
-
-/* A subclass of rich_location for showing problems with binary operations.
-
-   If enough location information is available, the ctor will make a
-   3-location rich_location of the form:
-
-     arg_0 op arg_1
-     ~~~~~ ^~ ~~~~~
-       |        |
-       |        arg1 type
-       arg0 type
-
-   labelling the types of the arguments if SHOW_TYPES is true.
-
-   Otherwise, it will fall back to a 1-location rich_location using the
-   compound location within LOC:
-
-     arg_0 op arg_1
-     ~~~~~~^~~~~~~~
-
-   for which we can't label the types.  */
-
-class binary_op_rich_location : public gcc_rich_location
-{
- public:
-  binary_op_rich_location (const op_location_t &loc,
-			   tree arg0, tree arg1,
-			   bool show_types);
-
- private:
-  static bool use_operator_loc_p (const op_location_t &loc,
-				  tree arg0, tree arg1);
-
-  maybe_range_label_for_tree_type_mismatch m_label_for_arg0;
-  maybe_range_label_for_tree_type_mismatch m_label_for_arg1;
-};
-
 #endif /* GCC_RICH_LOCATION_H */
