diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 8732b7dc71b..cc7c1947f9e 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -824,6 +824,10 @@ typedef struct ptrmem_cst * ptrmem_cst_t;
 /* The name of the overload set.  */
 #define OVL_NAME(NODE) DECL_NAME (OVL_FIRST (NODE))
 
+/* The source location of this OVL_USING_P overload.  */
+#define OVL_SOURCE_LOCATION(NODE) \
+  (((struct tree_overload*)OVERLOAD_CHECK (NODE))->loc)
+
 /* Whether this is a set of overloaded functions.  TEMPLATE_DECLS are
    always wrapped in an OVERLOAD, so we don't need to check them
    here.  */
@@ -838,6 +842,7 @@ typedef struct ptrmem_cst * ptrmem_cst_t;
 struct GTY(()) tree_overload {
   struct tree_common common;
   tree function;
+  location_t loc;
 };
 
 /* Iterator for a 1 dimensional overload.  Permits iterating over the
@@ -895,6 +900,7 @@ class ovl_iterator {
   }
   bool purview_p () const;
   bool exporting_p () const;
+  location_t source_location () const;
 
  public:
   tree remove_node (tree head)
diff --git a/gcc/cp/module.cc b/gcc/cp/module.cc
index f5966fc8c1c..5bb3e824acb 100644
--- a/gcc/cp/module.cc
+++ b/gcc/cp/module.cc
@@ -2581,7 +2581,7 @@ public:
     void add_namespace_context (depset *, tree ns);
 
   private:
-    static bool add_binding_entity (tree, WMB_Flags, void *);
+    static bool add_binding_entity (tree, WMB_Flags, void *, location_t);
 
   public:
     bool add_namespace_entities (tree ns, bitmap partitions);
@@ -13122,7 +13122,8 @@ struct add_binding_data
 /* Return true if we are, or contain something that is exported.  */
 
 bool
-depset::hash::add_binding_entity (tree decl, WMB_Flags flags, void *data_)
+depset::hash::add_binding_entity (tree decl, WMB_Flags flags, void *data_,
+				  location_t loc)
 {
   auto data = static_cast <add_binding_data *> (data_);
   decl = strip_using_decl (decl);
@@ -13185,7 +13186,6 @@ depset::hash::add_binding_entity (tree decl, WMB_Flags flags, void *data_)
 		{
 		  if (!(flags & WMB_Hidden))
 		    d->clear_hidden_binding ();
-		  OVL_PURVIEW_P (d->get_entity ()) = true;
 		  if (flags & WMB_Export)
 		    OVL_EXPORT_P (d->get_entity ()) = true;
 		  return bool (flags & WMB_Export);
@@ -13229,6 +13229,7 @@ depset::hash::add_binding_entity (tree decl, WMB_Flags flags, void *data_)
 	  OVL_PURVIEW_P (decl) = true;
 	  if (flags & WMB_Export)
 	    OVL_EXPORT_P (decl) = true;
+	  OVL_SOURCE_LOCATION (decl) = loc;
 	}
 
       depset *dep = data->hash->make_dependency
@@ -13616,7 +13617,10 @@ depset::hash::find_dependencies (module_state *module)
 	      dump.indent ();
 	      walker.begin ();
 	      if (current->get_entity_kind () == EK_USING)
-		walker.tree_node (OVL_FUNCTION (decl));
+		{
+		  module->note_location (OVL_SOURCE_LOCATION (decl));
+		  walker.tree_node (OVL_FUNCTION (decl));
+		}
 	      else if (TREE_VISITED (decl))
 		/* A global tree.  */;
 	      else if (item->get_entity_kind () == EK_NAMESPACE)
@@ -15114,6 +15118,7 @@ module_state::write_cluster (elf_out *to, depset *scc[], unsigned size,
 		depset *dep = b->deps[jx];
 		tree bound = dep->get_entity ();
 		unsigned flags = 0;
+		location_t loc = UNKNOWN_LOCATION;
 		if (dep->get_entity_kind () == depset::EK_USING)
 		  {
 		    tree ovl = bound;
@@ -15126,6 +15131,7 @@ module_state::write_cluster (elf_out *to, depset *scc[], unsigned size,
 		      flags |= cbf_using;
 		    if (OVL_EXPORT_P (ovl))
 		      flags |= cbf_export;
+		    loc = OVL_SOURCE_LOCATION (ovl);
 		  }
 		else
 		  {
@@ -15140,6 +15146,8 @@ module_state::write_cluster (elf_out *to, depset *scc[], unsigned size,
 		gcc_checking_assert (DECL_P (bound));
 
 		sec.i (flags);
+		if (flags & cbf_using)
+		  write_location (sec, loc);
 		sec.tree_node (bound);
 	      }
 
@@ -15281,6 +15289,10 @@ module_state::read_cluster (unsigned snum)
 		    && (flags & (cbf_using | cbf_export)))
 		  sec.set_overrun ();
 
+		location_t loc = UNKNOWN_LOCATION;
+		if (flags & cbf_using)
+		  loc = read_location (sec);
+
 		tree decl = sec.tree_node ();
 		if (sec.get_overrun ())
 		  break;
@@ -15291,8 +15303,7 @@ module_state::read_cluster (unsigned snum)
 		    if (type || !DECL_IMPLICIT_TYPEDEF_P (decl))
 		      sec.set_overrun ();
 
-		    type = build_lang_decl_loc (UNKNOWN_LOCATION,
-						USING_DECL,
+		    type = build_lang_decl_loc (loc, USING_DECL,
 						DECL_NAME (decl),
 						NULL_TREE);
 		    USING_DECL_DECLS (type) = decl;
@@ -15313,10 +15324,7 @@ module_state::read_cluster (unsigned snum)
 			if (decls)
 			  sec.set_overrun ();
 
-			/* FIXME: Propagate the location of the using-decl
-			   for use in diagnostics.  */
-			decls = build_lang_decl_loc (UNKNOWN_LOCATION,
-						     USING_DECL,
+			decls = build_lang_decl_loc (loc, USING_DECL,
 						     DECL_NAME (decl),
 						     NULL_TREE);
 			USING_DECL_DECLS (decls) = decl;
@@ -15339,6 +15347,7 @@ module_state::read_cluster (unsigned snum)
 			    OVL_PURVIEW_P (decls) = true;
 			    if (flags & cbf_export)
 			      OVL_EXPORT_P (decls) = true;
+			    OVL_SOURCE_LOCATION (decls) = loc;
 			  }
 
 			if (flags & cbf_hidden)
diff --git a/gcc/cp/name-lookup.cc b/gcc/cp/name-lookup.cc
index 96d7f938162..52c07e46d4f 100644
--- a/gcc/cp/name-lookup.cc
+++ b/gcc/cp/name-lookup.cc
@@ -4229,6 +4229,17 @@ ovl_iterator::exporting_p () const
   return OVL_EXPORT_P (ovl);
 }
 
+/* The declared source location of this using.  */
+
+location_t
+ovl_iterator::source_location () const
+{
+  gcc_checking_assert (using_p ());
+  if (TREE_CODE (ovl) == USING_DECL)
+    return DECL_SOURCE_LOCATION (ovl);
+  return OVL_SOURCE_LOCATION (ovl);
+}
+
 /* Given a namespace-level binding BINDING, walk it, calling CALLBACK
    for all decls of the current module.  When partitions are involved,
    decls might be mentioned more than once.   Return the accumulation of
@@ -4236,7 +4247,8 @@ ovl_iterator::exporting_p () const
 
 unsigned
 walk_module_binding (tree binding, bitmap partitions,
-		     bool (*callback) (tree decl, WMB_Flags, void *data),
+		     bool (*callback) (tree decl, WMB_Flags, void *data,
+				       location_t loc),
 		     void *data)
 {
   tree current = binding;
@@ -4249,6 +4261,7 @@ walk_module_binding (tree binding, bitmap partitions,
   if (tree type = MAYBE_STAT_TYPE (current))
     {
       WMB_Flags flags = WMB_None;
+      location_t loc = UNKNOWN_LOCATION;
       if (STAT_TYPE_HIDDEN_P (current))
 	flags = WMB_Flags (flags | WMB_Hidden);
       if (TREE_CODE (type) == USING_DECL)
@@ -4258,8 +4271,9 @@ walk_module_binding (tree binding, bitmap partitions,
 	    flags = WMB_Flags (flags | WMB_Purview);
 	  if (DECL_MODULE_EXPORT_P (type))
 	    flags = WMB_Flags (flags | WMB_Export);
+	  loc = DECL_SOURCE_LOCATION (type);
 	}
-      count += callback (type, flags, data);
+      count += callback (type, flags, data, loc);
       decl_hidden = STAT_DECL_HIDDEN_P (current);
     }
 
@@ -4270,6 +4284,7 @@ walk_module_binding (tree binding, bitmap partitions,
       if (!(decl_hidden && DECL_IS_UNDECLARED_BUILTIN (*iter)))
 	{
 	  WMB_Flags flags = WMB_None;
+	  location_t loc = UNKNOWN_LOCATION;
 	  if (decl_hidden)
 	    flags = WMB_Flags (flags | WMB_Hidden);
 	  if (iter.using_p ())
@@ -4279,8 +4294,9 @@ walk_module_binding (tree binding, bitmap partitions,
 		flags = WMB_Flags (flags | WMB_Purview);
 	      if (iter.exporting_p ())
 		flags = WMB_Flags (flags | WMB_Export);
+	      loc = iter.source_location ();
 	    }
-	  count += callback (*iter, flags, data);
+	  count += callback (*iter, flags, data, loc);
 	}
       decl_hidden = false;
     }
@@ -4319,13 +4335,14 @@ walk_module_binding (tree binding, bitmap partitions,
 		    WMB_Flags flags = WMB_None;
 		    if (maybe_dups)
 		      flags = WMB_Flags (flags | WMB_Dups);
-		    count += callback (bind, flags, data);
+		    count += callback (bind, flags, data, UNKNOWN_LOCATION);
 		  }
 		else if (STAT_HACK_P (bind) && MODULE_BINDING_PARTITION_P (bind))
 		  {
 		    if (tree btype = STAT_TYPE (bind))
 		      {
 			WMB_Flags flags = WMB_None;
+			location_t loc = UNKNOWN_LOCATION;
 			if (maybe_dups)
 			  flags = WMB_Flags (flags | WMB_Dups);
 			if (STAT_TYPE_HIDDEN_P (bind))
@@ -4337,8 +4354,9 @@ walk_module_binding (tree binding, bitmap partitions,
 			      flags = WMB_Flags (flags | WMB_Purview);
 			    if (DECL_MODULE_EXPORT_P (btype))
 			      flags = WMB_Flags (flags | WMB_Export);
+			    loc = DECL_SOURCE_LOCATION (btype);
 			  }
-			count += callback (btype, flags, data);
+			count += callback (btype, flags, data, loc);
 		      }
 		    bool part_hidden = STAT_DECL_HIDDEN_P (bind);
 		    for (ovl_iterator iter (MAYBE_STAT_DECL (STAT_DECL (bind)));
@@ -4350,6 +4368,7 @@ walk_module_binding (tree binding, bitmap partitions,
 			  (!(part_hidden && DECL_IS_UNDECLARED_BUILTIN (*iter)));
 
 			WMB_Flags flags = WMB_None;
+			location_t loc = UNKNOWN_LOCATION;
 			if (maybe_dups)
 			  flags = WMB_Flags (flags | WMB_Dups);
 			if (part_hidden)
@@ -4361,8 +4380,9 @@ walk_module_binding (tree binding, bitmap partitions,
 			      flags = WMB_Flags (flags | WMB_Purview);
 			    if (iter.exporting_p ())
 			      flags = WMB_Flags (flags | WMB_Export);
+			    loc = iter.source_location ();
 			  }
-			count += callback (*iter, flags, data);
+			count += callback (*iter, flags, data, loc);
 			part_hidden = false;
 		      }
 		  }
diff --git a/gcc/cp/name-lookup.h b/gcc/cp/name-lookup.h
index 5cf6ae6374a..8183cd50159 100644
--- a/gcc/cp/name-lookup.h
+++ b/gcc/cp/name-lookup.h
@@ -499,7 +499,8 @@ enum WMB_Flags
 };
 
 extern unsigned walk_module_binding (tree binding, bitmap partitions,
-				     bool (*)(tree decl, WMB_Flags, void *data),
+				     bool (*)(tree decl, WMB_Flags, void *data,
+					      location_t loc),
 				     void *data);
 extern tree add_imported_namespace (tree ctx, tree name, location_t,
 				    unsigned module,
diff --git a/gcc/cp/ptree.cc b/gcc/cp/ptree.cc
index 15e46752d01..4f7fc96cc74 100644
--- a/gcc/cp/ptree.cc
+++ b/gcc/cp/ptree.cc
@@ -299,6 +299,12 @@ cxx_print_xnode (FILE *file, tree node, int indent)
       print_node (file, "optype", BASELINK_OPTYPE (node), indent + 4);
       break;
     case OVERLOAD:
+      if (location_t loc = OVL_SOURCE_LOCATION (node))
+	{
+	  expanded_location xloc = expand_location (loc);
+	  indent_to (file, indent + 4);
+	  fprintf (file, "%s:%d:%d", xloc.file, xloc.line, xloc.column);
+	}
       print_node (file, "function", OVL_FUNCTION (node), indent + 4);
       print_node (file, "next", OVL_CHAIN (node), indent + 4);
       break;
diff --git a/gcc/cp/tree.cc b/gcc/cp/tree.cc
index dfd4a3a948b..21d8e0de329 100644
--- a/gcc/cp/tree.cc
+++ b/gcc/cp/tree.cc
@@ -2387,6 +2387,7 @@ ovl_insert (tree fn, tree maybe_ovl, int using_or_hidden)
 	    OVL_PURVIEW_P (maybe_ovl) = true;
 	  if (using_or_hidden > 2)
 	    OVL_EXPORT_P (maybe_ovl) = true;
+	  OVL_SOURCE_LOCATION (maybe_ovl) = input_location;
 	}
     }
   else
@@ -2532,6 +2533,7 @@ lookup_maybe_add (tree fns, tree lookup, bool deduping)
 		  {
 		    lookup = ovl_make (OVL_FUNCTION (fns), lookup);
 		    OVL_USING_P (lookup) = true;
+		    OVL_SOURCE_LOCATION (lookup) = OVL_SOURCE_LOCATION (fns);
 		  }
 		else
 		  lookup = lookup_add (OVL_FUNCTION (fns), lookup);
