From fde6f97e082794374ec8000e7625f9d1c20dbcb2 Mon Sep 17 00:00:00 2001 From: Paolo Carlini Date: Mon, 2 Sep 2013 09:42:39 +0000 Subject: [PATCH] PR c++/21682, implement DR 565 /cp 2013-09-02 Paolo Carlini 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. /testsuite 2013-09-02 Paolo Carlini PR c++/21682, implement DR 565 * g++.dg/template/using24.C: New. * g++.dg/template/using25.C: Likewise. * g++.dg/template/using26.C: Likewise. From-SVN: r202163 --- gcc/cp/ChangeLog | 6 +++ gcc/cp/name-lookup.c | 27 ++++++++++++-- gcc/testsuite/ChangeLog | 9 ++++- gcc/testsuite/g++.dg/template/using24.C | 30 +++++++++++++++ gcc/testsuite/g++.dg/template/using25.C | 17 +++++++++ gcc/testsuite/g++.dg/template/using26.C | 49 +++++++++++++++++++++++++ 6 files changed, 133 insertions(+), 5 deletions(-) create mode 100644 gcc/testsuite/g++.dg/template/using24.C create mode 100644 gcc/testsuite/g++.dg/template/using25.C create mode 100644 gcc/testsuite/g++.dg/template/using26.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 433c12d1741..7cafed9c3b5 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,9 @@ +2013-09-02 Paolo Carlini + + 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 * typeck.c (cp_build_binary_op): Add division by zero and shift diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c index b09e85bcb66..025a03cd9fa 100644 --- a/gcc/cp/name-lookup.c +++ b/gcc/cp/name-lookup.c @@ -2267,6 +2267,27 @@ pushdecl_with_scope (tree x, cp_binding_level *level, bool is_friend) 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 @@ -2324,8 +2345,7 @@ push_overloaded_decl_1 (tree decl, int flags, bool is_friend) 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); @@ -2561,8 +2581,7 @@ do_nonmember_using_decl (tree scope, tree name, tree oldval, tree oldtype, 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)); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 7ff5882d6b9..c87b30ac4b0 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,4 +1,11 @@ -2013-09-01 Jan Hubicka +2013-09-02 Paolo Carlini + + 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 * g++.dg/ipa/devirt-15.C: New testcase. diff --git a/gcc/testsuite/g++.dg/template/using24.C b/gcc/testsuite/g++.dg/template/using24.C new file mode 100644 index 00000000000..c3cdf93ec9b --- /dev/null +++ b/gcc/testsuite/g++.dg/template/using24.C @@ -0,0 +1,30 @@ +// PR c++/21682 + +template +struct t +{ + typedef typename T::type type; +}; +template<> class t{}; + +template struct t1{ }; +template<> struct t1 +{ + typedef int type; +}; + +namespace name1 +{ + template typename t::type begin(S const& s); + namespace name2 + { + template typename t1::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); } diff --git a/gcc/testsuite/g++.dg/template/using25.C b/gcc/testsuite/g++.dg/template/using25.C new file mode 100644 index 00000000000..6f4a7def7ab --- /dev/null +++ b/gcc/testsuite/g++.dg/template/using25.C @@ -0,0 +1,17 @@ +// PR c++/21682 + +namespace one { + template void fun(T); +} + +using one::fun; + +template void fun(T); // { dg-error "conflicts" } + +template void funr(T); + +namespace oner { + template void funr(T); +} + +using oner::funr; // { dg-error "conflicts" } diff --git a/gcc/testsuite/g++.dg/template/using26.C b/gcc/testsuite/g++.dg/template/using26.C new file mode 100644 index 00000000000..ca21857aad4 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/using26.C @@ -0,0 +1,49 @@ +// PR c++/21682 + +namespace one { + template int bar1(T); +} + +using one::bar1; + +template void bar1(T); + +template void bar1r(T); + +namespace oner { + template int bar1r(T); +} + +using oner::bar1r; + +namespace two { + template void bar2(T); +} + +using two::bar2; + +template void bar2(T); + +template void bar2r(T); + +namespace twor { + template void bar2r(T); +} + +using twor::bar2r; + +namespace three { + template void bar3(); +} + +using three::bar3; + +template void bar3(); + +template void bar3r(); + +namespace threer { + template void bar3r(); +} + +using threer::bar3r; -- 2.30.2