diff options
author | Paolo Carlini <paolo@gcc.gnu.org> | 2013-09-02 09:42:39 +0000 |
---|---|---|
committer | Paolo Carlini <paolo@gcc.gnu.org> | 2013-09-02 09:42:39 +0000 |
commit | fde6f97e082794374ec8000e7625f9d1c20dbcb2 (patch) | |
tree | ba3527b81eff0d88a2b16e3a9590ef37de65994b | |
parent | 576016fe9698e90bf397109f854821c4287a2c1c (diff) | |
download | gcc-fde6f97e082794374ec8000e7625f9d1c20dbcb2.zip gcc-fde6f97e082794374ec8000e7625f9d1c20dbcb2.tar.gz gcc-fde6f97e082794374ec8000e7625f9d1c20dbcb2.tar.bz2 |
PR c++/21682, implement DR 565
/cp
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.
/testsuite
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.
From-SVN: r202163
-rw-r--r-- | gcc/cp/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/cp/name-lookup.c | 27 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 9 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/template/using24.C | 30 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/template/using25.C | 17 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/template/using26.C | 49 |
6 files changed, 133 insertions, 5 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 433c12d..7cafed9 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,9 @@ +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 diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c index b09e85b..025a03c 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 7ff5882..c87b30a 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,4 +1,11 @@ -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. diff --git a/gcc/testsuite/g++.dg/template/using24.C b/gcc/testsuite/g++.dg/template/using24.C new file mode 100644 index 0000000..c3cdf93 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/using24.C @@ -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); } diff --git a/gcc/testsuite/g++.dg/template/using25.C b/gcc/testsuite/g++.dg/template/using25.C new file mode 100644 index 0000000..6f4a7de --- /dev/null +++ b/gcc/testsuite/g++.dg/template/using25.C @@ -0,0 +1,17 @@ +// 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" } diff --git a/gcc/testsuite/g++.dg/template/using26.C b/gcc/testsuite/g++.dg/template/using26.C new file mode 100644 index 0000000..ca21857 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/using26.C @@ -0,0 +1,49 @@ +// 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; |