}
/* CAND is a constructor candidate in joust in C++17 and up. If it copies a
- prvalue returned from a conversion function, replace CAND with the candidate
- for the conversion and return true. Otherwise, return false. */
+ prvalue returned from a conversion function, return true. Otherwise, return
+ false. */
static bool
-joust_maybe_elide_copy (z_candidate *&cand)
+joust_maybe_elide_copy (z_candidate *cand)
{
tree fn = cand->fn;
if (!DECL_COPY_CONSTRUCTOR_P (fn) && !DECL_MOVE_CONSTRUCTOR_P (fn))
(conv->type, DECL_CONTEXT (fn)));
z_candidate *uc = conv->cand;
if (DECL_CONV_FN_P (uc->fn))
- {
- cand = uc;
- return true;
- }
+ return true;
}
return false;
}
}
}
- /* Handle C++17 copy elision in [over.match.ctor] (direct-init) context. The
- standard currently says that only constructors are candidates, but if one
- copies a prvalue returned by a conversion function we want to treat the
- conversion as the candidate instead.
-
- Clang does something similar, as discussed at
- http://lists.isocpp.org/core/2017/10/3166.php
- http://lists.isocpp.org/core/2019/03/5721.php */
- int elided_tiebreaker = 0;
- if (len == 1 && cxx_dialect >= cxx17
- && DECL_P (cand1->fn)
- && DECL_COMPLETE_CONSTRUCTOR_P (cand1->fn)
- && !(cand1->flags & LOOKUP_ONLYCONVERTING))
- {
- bool elided1 = joust_maybe_elide_copy (cand1);
- bool elided2 = joust_maybe_elide_copy (cand2);
- /* As a tiebreaker below we will prefer a constructor to a conversion
- operator exposed this way. */
- elided_tiebreaker = elided2 - elided1;
- }
-
for (i = 0; i < len; ++i)
{
conversion *t1 = cand1->convs[i + off1];
if (winner)
return winner;
- /* Put this tiebreaker first, so that we don't try to look at second_conv of
- a constructor candidate that doesn't have one. */
- if (elided_tiebreaker)
- return elided_tiebreaker;
-
/* DR 495 moved this tiebreaker above the template ones. */
/* or, if not that,
the context is an initialization by user-defined conversion (see
}
}
+ /* DR2327: C++17 copy elision in [over.match.ctor] (direct-init) context.
+ The standard currently says that only constructors are candidates, but if
+ one copies a prvalue returned by a conversion function we prefer that.
+
+ Clang does something similar, as discussed at
+ http://lists.isocpp.org/core/2017/10/3166.php
+ http://lists.isocpp.org/core/2019/03/5721.php */
+ if (len == 1 && cxx_dialect >= cxx17
+ && DECL_P (cand1->fn)
+ && DECL_COMPLETE_CONSTRUCTOR_P (cand1->fn)
+ && !(cand1->flags & LOOKUP_ONLYCONVERTING))
+ {
+ bool elided1 = joust_maybe_elide_copy (cand1);
+ bool elided2 = joust_maybe_elide_copy (cand2);
+ winner = elided1 - elided2;
+ if (winner)
+ return winner;
+ }
+
/* or, if not that,
F1 is a non-template function and F2 is a template function
specialization. */