+2013-09-02 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/21682, implement DR 565
+ * name-lookup.c (compparms_for_decl_and_using_decl): New.
+ (push_overloaded_decl_1, do_nonmember_using_decl): Use it.
+
2013-08-30 Marek Polacek <polacek@redhat.com>
* typeck.c (cp_build_binary_op): Add division by zero and shift
return ret;
}
+/* Helper function for push_overloaded_decl_1 and do_nonmember_using_decl.
+ Compares the parameter-type-lists of DECL1 and DECL2 and returns false
+ if they are different. If the DECLs are template functions, the return
+ types and the template parameter lists are compared too (DR 565). */
+
+static bool
+compparms_for_decl_and_using_decl (tree decl1, tree decl2)
+{
+ if (!compparms (TYPE_ARG_TYPES (TREE_TYPE (decl1)),
+ TYPE_ARG_TYPES (TREE_TYPE (decl2))))
+ return false;
+
+ if (! DECL_FUNCTION_TEMPLATE_P (decl1)
+ || ! DECL_FUNCTION_TEMPLATE_P (decl2))
+ return true;
+
+ return (comp_template_parms (DECL_TEMPLATE_PARMS (decl1),
+ DECL_TEMPLATE_PARMS (decl2))
+ && same_type_p (TREE_TYPE (TREE_TYPE (decl1)),
+ TREE_TYPE (TREE_TYPE (decl2))));
+}
/* DECL is a FUNCTION_DECL for a non-member function, which may have
other definitions already in place. We get around this by making
if (TREE_CODE (tmp) == OVERLOAD && OVL_USED (tmp)
&& !(flags & PUSH_USING)
- && compparms (TYPE_ARG_TYPES (TREE_TYPE (fn)),
- TYPE_ARG_TYPES (TREE_TYPE (decl)))
+ && compparms_for_decl_and_using_decl (fn, decl)
&& ! decls_match (fn, decl))
diagnose_name_conflict (decl, fn);
break;
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))))
+ else if (compparms_for_decl_and_using_decl (new_fn, old_fn))
{
gcc_assert (!DECL_ANTICIPATED (old_fn)
|| DECL_HIDDEN_FRIEND_P (old_fn));
-2013-09-01 Jan Hubicka <jh@suse.cz>
+2013-09-02 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/21682, implement DR 565
+ * g++.dg/template/using24.C: New.
+ * g++.dg/template/using25.C: Likewise.
+ * g++.dg/template/using26.C: Likewise.
+
+2013-09-01 Jan Hubicka <jh@suse.cz>
* g++.dg/ipa/devirt-15.C: New testcase.
--- /dev/null
+// 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); }
--- /dev/null
+// PR c++/21682
+
+namespace one {
+ template<typename T> void fun(T);
+}
+
+using one::fun;
+
+template<typename T> void fun(T); // { dg-error "conflicts" }
+
+template<typename T> void funr(T);
+
+namespace oner {
+ template<typename T> void funr(T);
+}
+
+using oner::funr; // { dg-error "conflicts" }
--- /dev/null
+// PR c++/21682
+
+namespace one {
+ template<typename T> int bar1(T);
+}
+
+using one::bar1;
+
+template<typename T> void bar1(T);
+
+template<typename T> void bar1r(T);
+
+namespace oner {
+ template<typename T> int bar1r(T);
+}
+
+using oner::bar1r;
+
+namespace two {
+ template<typename T, typename U> void bar2(T);
+}
+
+using two::bar2;
+
+template<typename T> void bar2(T);
+
+template<typename T> void bar2r(T);
+
+namespace twor {
+ template<typename T, typename U> void bar2r(T);
+}
+
+using twor::bar2r;
+
+namespace three {
+ template<int i> void bar3();
+}
+
+using three::bar3;
+
+template<typename T> void bar3();
+
+template<typename T> void bar3r();
+
+namespace threer {
+ template<int i> void bar3r();
+}
+
+using threer::bar3r;