summaryrefslogtreecommitdiff
path: root/gcc/cp/name-lookup.c
diff options
context:
space:
mode:
authorpaolo <paolo@138bc75d-0d04-0410-961f-82ee72b054a4>2013-09-02 09:42:39 +0000
committerpaolo <paolo@138bc75d-0d04-0410-961f-82ee72b054a4>2013-09-02 09:42:39 +0000
commit894d126ec11fa17fb616f28a1555992560b9dd07 (patch)
treeba3527b81eff0d88a2b16e3a9590ef37de65994b /gcc/cp/name-lookup.c
parent0a3fd7ce64e8e0098411ae728253299d9d686aab (diff)
downloadgcc-894d126ec11fa17fb616f28a1555992560b9dd07.tar.gz
/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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@202163 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/cp/name-lookup.c')
-rw-r--r--gcc/cp/name-lookup.c27
1 files changed, 23 insertions, 4 deletions
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));