===================================================================
@@ -2562,7 +2562,20 @@ do_nonmember_using_decl (tree scope, tree name, tr
else if (TREE_CODE (tmp1) == OVERLOAD && OVL_USED (tmp1))
continue; /* this is a using decl */
else if (compparms (TYPE_ARG_TYPES (TREE_TYPE (new_fn)),
- TYPE_ARG_TYPES (TREE_TYPE (old_fn))))
+ TYPE_ARG_TYPES (TREE_TYPE (old_fn)))
+ /* DR 565: If a function template declaration in
+ namespace scope has the same name, parameter-
+ type-list, return type, and template parameter
+ list as a function template introduced by a
+ using-declaration, the program is ill-formed. */
+ && (TREE_CODE (new_fn) != TEMPLATE_DECL
+ || TREE_CODE (old_fn) != TEMPLATE_DECL
+ || (comp_template_parms
+ (DECL_TEMPLATE_PARMS (new_fn),
+ DECL_TEMPLATE_PARMS (old_fn))
+ && (same_type_p
+ (TREE_TYPE (TREE_TYPE (new_fn)),
+ TREE_TYPE (TREE_TYPE (old_fn)))))))
{
gcc_assert (!DECL_ANTICIPATED (old_fn)
|| DECL_HIDDEN_FRIEND_P (old_fn));
===================================================================
@@ -0,0 +1,30 @@
+// PR c++/21682
+
+template <class T>
+struct t
+{
+ typedef typename T::type type;
+};
+template<> class t<int>{};
+
+template <class T> struct t1{ };
+template<> struct t1<int>
+{
+ typedef int type;
+};
+
+namespace name1
+{
+ template <class S> typename t<S>::type begin(S const& s);
+ namespace name2
+ {
+ template <class S> typename t1<S>::type begin(S const& s);
+ }
+ using name2::begin;
+}
+
+/* Test calling the function. */
+int f(int a) { return name1::begin(a); }
+
+struct aa { typedef double type; };
+double g(aa t) { return name1::begin(t); }
===================================================================
@@ -0,0 +1,9 @@
+// PR c++/21682
+
+namespace one {
+ template<typename T> void fun(T);
+}
+
+using one::fun;
+
+template<typename T> void fun(T); // { dg-error "conflicts" }