diff --git a/gcc/cp/call.cc b/gcc/cp/call.cc
index a75e2e5e3af..3287f77b59b 100644
--- a/gcc/cp/call.cc
+++ b/gcc/cp/call.cc
@@ -13261,6 +13261,28 @@ joust (struct z_candidate *cand1, struct z_candidate *cand2, bool warn,
   else if (cand2->rewritten ())
     return 1;
 
+  /* F1 and F2 are generated from class template argument deduction for a class
+     D, and F2 is generated from inheriting constructors from a base class of D
+     while F1 is not, and for each explicit function argument, the corresponding
+     parameters of F1 and F2 are either both ellipses or have the same type  */
+  if (deduction_guide_p (cand1->fn))
+    {
+      bool inherited1 = inherited_guide_p (cand1->fn);
+      bool inherited2 = inherited_guide_p (cand2->fn);
+      if (int diff = inherited2 - inherited1)
+	{
+	  for (i = 0; i < len; ++i)
+	    {
+	      conversion *t1 = cand1->convs[i + off1];
+	      conversion *t2 = cand2->convs[i + off2];
+	      if (!same_type_p (t1->type, t2->type))
+		break;
+	    }
+	  if (i == len)
+	    return diff;
+	}
+    }
+
   /* F1 is generated from a deduction-guide (13.3.1.8) and F2 is not */
   if (deduction_guide_p (cand1->fn))
     {
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 0c25ec5a04e..0b76fef0df4 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -2973,8 +2973,11 @@ struct GTY(()) lang_decl_fn {
      chained here.  This pointer thunks to return pointer thunks
      will be chained on the return pointer thunk.
      For a DECL_CONSTUCTOR_P FUNCTION_DECL, this is the base from
-     whence we inherit.  Otherwise, it is the class in which a
-     (namespace-scope) friend is defined (if any).   */
+     whence we inherit.
+     For a deduction_guide_p FUNCTION_DECL, this is the base class
+     from whence we inherited the guide (if any).
+     Otherwise, it is the class in which a (namespace-scope) friend
+     is defined (if any).  */
   tree context;
 
   union lang_decl_u5
@@ -7655,6 +7658,7 @@ extern bool deduction_guide_p			(const_tree);
 extern bool copy_guide_p			(const_tree);
 extern bool template_guide_p			(const_tree);
 extern bool builtin_guide_p			(const_tree);
+extern bool inherited_guide_p			(const_tree);
 extern void store_explicit_specifier		(tree, tree);
 extern tree lookup_explicit_specifier		(tree);
 extern tree lookup_imported_hidden_friend	(tree);
diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc
index d468a3037b6..b518e6d5185 100644
--- a/gcc/cp/pt.cc
+++ b/gcc/cp/pt.cc
@@ -29678,6 +29678,26 @@ builtin_guide_p (const_tree fn)
   return true;
 }
 
+/* True if FN is a C++23 inherited guide.  */
+
+bool
+inherited_guide_p (const_tree fn)
+{
+  gcc_assert (deduction_guide_p (fn));
+  return LANG_DECL_FN_CHECK (fn)->context != NULL_TREE;
+}
+
+/* Set the base class from which this transformed guide was inherited
+   as part of C++23 inherited CTAD.  */
+
+static void
+set_inherited_guide_context (const_tree fn, tree context)
+{
+  gcc_assert (deduction_guide_p (fn));
+  LANG_DECL_FN_CHECK (fn)->context = context;
+}
+
+
 /* OLDDECL is a _DECL for a template parameter.  Return a similar parameter at
    LEVEL:INDEX, using tsubst_args and complain for substitution into non-type
    template parameter types.  Note that the handling of template template
@@ -30448,6 +30468,7 @@ alias_ctad_tweaks (tree tmpl, tree uguides)
 	  TREE_TYPE (fprime) = fntype;
 	  if (TREE_CODE (fprime) == TEMPLATE_DECL)
 	    TREE_TYPE (DECL_TEMPLATE_RESULT (fprime)) = fntype;
+	  set_inherited_guide_context (fprime, utype);
 	}
 
       aguides = lookup_add (fprime, aguides);
@@ -30479,11 +30500,14 @@ inherited_ctad_tweaks (tree tmpl, tree ctor, tsubst_flags_t complain)
      template specialization with the template argument list of A but with C as
      the template.  */
 
-  /* FIXME: Also recognize inherited constructors of the form 'using C::B::B',
-     which seem to be represented with TYPENAME_TYPE C::B as USING_DECL_SCOPE?
-     And recognize constructors inherited from a non-dependent base class, which
-     seem to be missing from the overload set entirely?  */
   tree scope = USING_DECL_SCOPE (ctor);
+  if (TREE_CODE (scope) == TYPENAME_TYPE
+      && (TYPE_IDENTIFIER (TYPE_CONTEXT (scope))
+	  == TYPENAME_TYPE_FULLNAME (scope)))
+    /* Recognize using B<T>::B::B; as an inheriting constructor.  */
+    /* FIXME: Also recognize using C::B::B; ?  We might have to call
+       resolve_typename_type for that.  */
+    scope = TYPE_CONTEXT (scope);
   if (!CLASS_TYPE_P (scope)
       || !CLASSTYPE_TEMPLATE_INFO (scope)
       || !PRIMARY_TEMPLATE_P (CLASSTYPE_TI_TEMPLATE (scope)))
@@ -30617,10 +30641,15 @@ ctor_deduction_guides_for (tree tmpl, tsubst_flags_t complain)
     }
 
   if (cxx_dialect >= cxx23)
-    for (tree ctor : ovl_range (CLASSTYPE_CONSTRUCTORS (type)))
-      if (TREE_CODE (ctor) == USING_DECL)
-	{
-	  tree uguides = inherited_ctad_tweaks (tmpl, ctor, complain);
+    /* FIXME: CLASSTYPE_CONSTRUCTORS seems to omit (dependent) inherited
+       constructors if e.g.  there's a user-defined constructor.  So instead
+       iterate over TYPE_FIELDS manually to robustly find all relevant using
+       decls.  */
+    for (tree field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
+      if (TREE_CODE (field) == USING_DECL
+	  && DECL_NAME (field) == ctor_identifier)
+	{
+	  tree uguides = inherited_ctad_tweaks (tmpl, field, complain);
 	  if (uguides)
 	    cands = lookup_add (uguides, cands);
 	}
diff --git a/gcc/testsuite/g++.dg/cpp23/class-deduction-inherited4.C b/gcc/testsuite/g++.dg/cpp23/class-deduction-inherited4.C
index 5e3a7f42919..bc0d5cc53d4 100644
--- a/gcc/testsuite/g++.dg/cpp23/class-deduction-inherited4.C
+++ b/gcc/testsuite/g++.dg/cpp23/class-deduction-inherited4.C
@@ -13,10 +13,10 @@ using ty1 = B<int>;
 
 template<class T=void>
 struct C : A<int> {
-  using A<int>::A; // FIXME: we don't notice this one either
+  using A<int>::A;
 };
 
-using ty2 = decltype(C(0)); // { dg-bogus "" "" { xfail *-*-* } }
+using ty2 = decltype(C(0));
 using ty2 = C<void>;
 
 template<class T>
@@ -30,3 +30,14 @@ using ty3 = D<int>;
 A(int) -> A<char>; // FIXME: we need to rebuild the guides of D
 using ty4 = decltype(D(0));
 using ty4 = D<char>; // { dg-bogus "conflicting" "" { xfail *-*-* } }
+
+template<class T>
+struct E { E(T); };
+
+template<class T>
+struct F : E<T> {
+  using E<T>::E::E;
+};
+
+using ty5 = decltype(F(0));
+using ty5 = F<int>;
diff --git a/gcc/testsuite/g++.dg/cpp23/class-deduction-inherited5.C b/gcc/testsuite/g++.dg/cpp23/class-deduction-inherited5.C
new file mode 100644
index 00000000000..7eee8664b10
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp23/class-deduction-inherited5.C
@@ -0,0 +1,25 @@
+// PR c++/116276
+// { dg-do compile { target c++20 } }
+
+template<class T>
+struct Base1 { };
+
+template<class T>
+struct Base2 { };
+
+template<class T = int>
+struct Derived : public Base1<T>, Base2<T> {
+  using Base1<T>::Base1;
+  using Base2<T>::Base2;
+};
+
+Derived d;
+
+template<class T = int>
+struct Derived2 : public Base1<T>, Base2<T> {
+  using Base1<T>::Base1;
+  using Base2<T>::Base2;
+  Derived2();
+};
+
+Derived2 d2;
