diff options
author | Jason Merrill <jason@redhat.com> | 2010-06-26 17:34:36 -0400 |
---|---|---|
committer | Jason Merrill <jason@gcc.gnu.org> | 2010-06-26 17:34:36 -0400 |
commit | cef62ad4b8a7639969639eaf77efb69fdcb7491f (patch) | |
tree | 8ab96391526abd64104dcc6fc5e7d59416087ad1 | |
parent | d9816849ed076273403f2fcf4913134dbf2acdb3 (diff) | |
download | gcc-cef62ad4b8a7639969639eaf77efb69fdcb7491f.zip gcc-cef62ad4b8a7639969639eaf77efb69fdcb7491f.tar.gz gcc-cef62ad4b8a7639969639eaf77efb69fdcb7491f.tar.bz2 |
call.c (add_function_candidate): Set LOOKUP_COPY_PARM for any constructor called with a single argument that...
* call.c (add_function_candidate): Set LOOKUP_COPY_PARM for any
constructor called with a single argument that takes a reference
to the constructor's class.
(BAD_CONVERSION_RANK): New.
(compare_ics): Use it to compare bad ICSes.
From-SVN: r161443
-rw-r--r-- | gcc/cp/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/cp/call.c | 57 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp0x/explicit5.C | 25 |
4 files changed, 76 insertions, 18 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 3093f0d..e9d85c3 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,11 @@ +2010-06-26 Jason Merrill <jason@redhat.com> + + * call.c (add_function_candidate): Set LOOKUP_COPY_PARM for any + constructor called with a single argument that takes a reference + to the constructor's class. + (BAD_CONVERSION_RANK): New. + (compare_ics): Use it to compare bad ICSes. + 2010-06-25 Joseph Myers <joseph@codesourcery.com> * lang-specs.h: Remove +e handling. diff --git a/gcc/cp/call.c b/gcc/cp/call.c index 55089ed..faaab10 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -122,6 +122,11 @@ struct conversion { : (NODE)->user_conv_p ? cr_user \ : (NODE)->rank) +#define BAD_CONVERSION_RANK(NODE) \ + ((NODE)->ellipsis_p ? cr_ellipsis \ + : (NODE)->user_conv_p ? cr_user \ + : (NODE)->rank) + static struct obstack conversion_obstack; static bool conversion_obstack_initialized; @@ -1386,9 +1391,12 @@ reference_binding (tree rto, tree rfrom, tree expr, bool c_cast_p, int flags) conversion operator). */ flags |= LOOKUP_NO_TEMP_BIND; - /* Temporaries are copy-initialized, except for this hack to allow - explicit conversion ops to the copy ctor. See also - add_function_candidate. */ + /* Core issue 899: When [copy-]initializing a temporary to be bound + to the first parameter of a copy constructor (12.8) called with + a single argument in the context of direct-initialization, + explicit conversion functions are also considered. + + So don't set LOOKUP_ONLYCONVERTING in that case. */ if (!(flags & LOOKUP_COPY_PARM)) flags |= LOOKUP_ONLYCONVERTING; @@ -1618,6 +1626,8 @@ add_function_candidate (struct z_candidate **candidates, tree parmtype = TREE_VALUE (parmnode); int lflags = flags; + parmnode = TREE_CHAIN (parmnode); + /* The type of the implicit object parameter ('this') for overload resolution is not always the same as for the function itself; conversion functions are considered to @@ -1634,13 +1644,25 @@ add_function_candidate (struct z_candidate **candidates, parmtype = build_pointer_type (parmtype); } - if (ctype && i == 0 && DECL_COPY_CONSTRUCTOR_P (fn) - && (len-skip == 1)) + /* Core issue 899: When [copy-]initializing a temporary to be bound + to the first parameter of a copy constructor (12.8) called with + a single argument in the context of direct-initialization, + explicit conversion functions are also considered. + + So set LOOKUP_COPY_PARM to let reference_binding know that + it's being called in that context. We generalize the above + to handle move constructors and template constructors as well; + the standardese should soon be updated similarly. */ + if (ctype && i == 0 && (len-skip == 1) + && !(flags & LOOKUP_ONLYCONVERTING) + && DECL_CONSTRUCTOR_P (fn) + && parmtype != error_mark_node + && (same_type_ignoring_top_level_qualifiers_p + (non_reference (parmtype), ctype))) { - /* Hack: Direct-initialize copy parm (i.e. suppress - LOOKUP_ONLYCONVERTING) to make explicit conversion ops - work. See also reference_binding. */ lflags |= LOOKUP_COPY_PARM; + /* We allow user-defined conversions within init-lists, but + not for the copy constructor. */ if (flags & LOOKUP_NO_COPY_CTOR_CONVERSION) lflags |= LOOKUP_NO_CONVERSION; } @@ -1668,9 +1690,6 @@ add_function_candidate (struct z_candidate **candidates, if (t->bad_p) viable = -1; - - if (parmnode) - parmnode = TREE_CHAIN (parmnode); } out: @@ -6741,14 +6760,16 @@ compare_ics (conversion *ics1, conversion *ics2) if (rank1 == cr_bad) { - /* XXX Isn't this an extension? */ - /* Both ICS are bad. We try to make a decision based on what - would have happened if they'd been good. */ - if (ics1->user_conv_p > ics2->user_conv_p - || ics1->rank > ics2->rank) + /* Both ICS are bad. We try to make a decision based on what would + have happened if they'd been good. This is not an extension, + we'll still give an error when we build up the call; this just + helps us give a more helpful error message. */ + rank1 = BAD_CONVERSION_RANK (ics1); + rank2 = BAD_CONVERSION_RANK (ics2); + + if (rank1 > rank2) return -1; - else if (ics1->user_conv_p < ics2->user_conv_p - || ics1->rank < ics2->rank) + else if (rank1 < rank2) return 1; /* We couldn't make up our minds; try to figure it out below. */ diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 3f88e7d..ea6169e 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2010-06-26 Jason Merrill <jason@redhat.com> + + * g++.dg/cpp0x/explicit5.C: New. + 2010-06-26 Richard Guenther <rguenther@suse.de> PR tree-optimization/44393 diff --git a/gcc/testsuite/g++.dg/cpp0x/explicit5.C b/gcc/testsuite/g++.dg/cpp0x/explicit5.C new file mode 100644 index 0000000..88a4707 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/explicit5.C @@ -0,0 +1,25 @@ +// test for extension of DR 899 to handle template ctors +// { dg-options "-std=c++0x" } +// { dg-do run } + +int r = 1; + +struct C { + C() { } + template <class T = int> C(C&, T = 0) { r = 0; } +}; + +C c; + +struct A +{ + explicit operator C&() const { return c; } +}; + +int main() +{ + A a; + C c2 (a); + + return r; +} |