aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaolo Carlini <paolo@gcc.gnu.org>2013-09-02 09:42:39 +0000
committerPaolo Carlini <paolo@gcc.gnu.org>2013-09-02 09:42:39 +0000
commitfde6f97e082794374ec8000e7625f9d1c20dbcb2 (patch)
treeba3527b81eff0d88a2b16e3a9590ef37de65994b
parent576016fe9698e90bf397109f854821c4287a2c1c (diff)
downloadgcc-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/ChangeLog6
-rw-r--r--gcc/cp/name-lookup.c27
-rw-r--r--gcc/testsuite/ChangeLog9
-rw-r--r--gcc/testsuite/g++.dg/template/using24.C30
-rw-r--r--gcc/testsuite/g++.dg/template/using25.C17
-rw-r--r--gcc/testsuite/g++.dg/template/using26.C49
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;