This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
C++ PATCH: Fix PR5189
- From: Mark Mitchell <mark at codesourcery dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Fri, 12 Apr 2002 18:32:32 -0700
- Subject: C++ PATCH: Fix PR5189
This patch fixes C++ PR 5189, whereby we ended up in an infinite
loop in the compiler since we were trying to use a copy constructor
whose only argument was a value parameter of the destination type.
Boostrapped and tested on i686-pc-linux-gnu, applied on the mainline
and on the branch.
--
Mark Mitchell mark@codesourcery.com
CodeSourcery, LLC http://www.codesourcery.com
2002-04-12 Mark Mitchell <mark@codesourcery.com>
PR c++/5189.
* call.c (add_template_candidate_real): Do not treat member
templates as copy constructors.
2002-04-12 Mark Mitchell <mark@codesourcery.com>
PR c++/5189.
* g++.dg/template/copy1.C: New test.
Index: testsuite/g++.dg/template/copy1.C
===================================================================
RCS file: testsuite/g++.dg/template/copy1.C
diff -N testsuite/g++.dg/template/copy1.C
*** /dev/null 1 Jan 1970 00:00:00 -0000
--- testsuite/g++.dg/template/copy1.C 13 Apr 2002 01:28:12 -0000
***************
*** 0 ****
--- 1,14 ----
+ // { dg-do compile }
+
+ // Origin: hkluender@otg.com
+
+ // PR 5189
+
+ struct A
+ {
+ A(A&); // { dg-error "candidate" "" }
+ template <class T> A(T);
+ };
+
+ A a = 0; // { dg-error "no matching function|initializing" "" }
+
Index: cp/call.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/call.c,v
retrieving revision 1.307.2.5
diff -c -p -r1.307.2.5 call.c
*** cp/call.c 27 Mar 2002 19:13:59 -0000 1.307.2.5
--- cp/call.c 13 Apr 2002 01:28:13 -0000
*************** add_template_candidate_real (candidates,
*** 2238,2243 ****
--- 2238,2273 ----
if (fn == error_mark_node)
return candidates;
+ /* In [class.copy]:
+
+ A member function template is never instantiated to perform the
+ copy of a class object to an object of its class type.
+
+ It's a little unclear what this means; the standard explicitly
+ does allow a template to be used to copy a class. For example,
+ in:
+
+ struct A {
+ A(A&);
+ template <class T> A(const T&);
+ };
+ const A f ();
+ void g () { A a (f ()); }
+
+ the member template will be used to make the copy. The section
+ quoted above appears in the paragraph that forbids constructors
+ whose only parameter is (a possibly cv-qualified variant of) the
+ class type, and a logical interpretation is that the intent was
+ to forbid the instantiation of member templates which would then
+ have that form. */
+ if (DECL_CONSTRUCTOR_P (fn) && list_length (arglist) == 2)
+ {
+ tree arg_types = FUNCTION_FIRST_USER_PARMTYPE (fn);
+ if (arg_types && same_type_p (TYPE_MAIN_VARIANT (TREE_VALUE
(arg_types)),
+ ctype))
+ return candidates;
+ }
+
if (obj != NULL_TREE)
/* Aha, this is a conversion function. */
cand = add_conv_candidate (candidates, fn, obj, arglist);