Patchwork [C++] PR 21682 (DR 565)

login
register
mail settings
Submitter Paolo Carlini
Date Sept. 1, 2013, 5:02 p.m.
Message ID <52237317.60400@oracle.com>
Download mbox | patch
Permalink /patch/271631/
State New
Headers show

Comments

Paolo Carlini - Sept. 1, 2013, 5:02 p.m.
Hi,

this patch resolves the bug by implementing the resolution of DR 565 
(DRWP): for template functions, in order to establish that the program 
is ill-formed we want to check return type and template parameter list 
too. Thus, in practice, we want to accept the reduced testcase which 
came with c++/21682 (using24.C) and reject the testcase which I 
discussed in DR 565 (using25.C) (*)

Booted & tested x86_64-linux.

Thanks!
Paolo.

(*) Likewise current clang.

//////////////////////////
/cp
2013-09-01  Paolo Carlini  <paolo.carlini@oracle.com>

	PR c++/21682, implement DR 565
	* name-lookup.c (do_nonmember_using_decl): For template function,
	check return type and template parameter list too.

/testsuite
2013-09-01  Paolo Carlini  <paolo.carlini@oracle.com>

	PR c++/21682, implement DR 565
	* g++.dg/template/using24.C: New.
	* g++.dg/template/using25.C: Likewise.
Paolo Carlini - Sept. 1, 2013, 5:40 p.m.
.. consider this withdrawn, I have to fix another very similar check 
elsewhere.

Paolo.

Patch

Index: cp/name-lookup.c
===================================================================
--- cp/name-lookup.c	(revision 202141)
+++ cp/name-lookup.c	(working copy)
@@ -2562,7 +2562,20 @@  do_nonmember_using_decl (tree scope, tree name, tr
 		  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))))
+				      TYPE_ARG_TYPES (TREE_TYPE (old_fn)))
+			   /* DR 565: If a function template declaration in
+			      namespace scope has the same name, parameter-
+			      type-list, return type, and template parameter
+			      list as a function template introduced by a
+			      using-declaration, the program is ill-formed.  */
+			   && (TREE_CODE (new_fn) != TEMPLATE_DECL
+			       || TREE_CODE (old_fn) != TEMPLATE_DECL
+			       || (comp_template_parms
+				   (DECL_TEMPLATE_PARMS (new_fn),
+				    DECL_TEMPLATE_PARMS (old_fn))
+				   && (same_type_p
+				       (TREE_TYPE (TREE_TYPE (new_fn)),
+					TREE_TYPE (TREE_TYPE (old_fn)))))))
 		    {
 		      gcc_assert (!DECL_ANTICIPATED (old_fn)
 				  || DECL_HIDDEN_FRIEND_P (old_fn));
Index: testsuite/g++.dg/template/using24.C
===================================================================
--- testsuite/g++.dg/template/using24.C	(revision 0)
+++ testsuite/g++.dg/template/using24.C	(working copy)
@@ -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); }
Index: testsuite/g++.dg/template/using25.C
===================================================================
--- testsuite/g++.dg/template/using25.C	(revision 0)
+++ testsuite/g++.dg/template/using25.C	(working copy)
@@ -0,0 +1,9 @@ 
+// PR c++/21682
+
+namespace one {
+  template<typename T> void fun(T);
+}
+
+using one::fun;
+
+template<typename T> void fun(T);  // { dg-error "conflicts" }