Commit 218e9dde by Jason Merrill Committed by Jason Merrill

DR 2137 - copy-constructor rank in list-initialization

	* call.c (implicit_conversion): If we choose a copy constructor
	for list-initialization from the same type, the conversion is an
	exact match.

From-SVN: r235219
parent 06ec22b7
2016-04-19 Jason Merrill <jason@redhat.com> 2016-04-19 Jason Merrill <jason@redhat.com>
DR 2137
* call.c (implicit_conversion): If we choose a copy constructor
for list-initialization from the same type, the conversion is an
exact match.
* constexpr.c (breaks): Handle EXIT_EXPR. * constexpr.c (breaks): Handle EXIT_EXPR.
(cxx_eval_loop_expr): Handle COMPOUND_EXPR body. (cxx_eval_loop_expr): Handle COMPOUND_EXPR body.
(cxx_eval_constant_expression): Handle EXIT_EXPR, improve handling (cxx_eval_constant_expression): Handle EXIT_EXPR, improve handling
......
...@@ -1862,7 +1862,24 @@ implicit_conversion (tree to, tree from, tree expr, bool c_cast_p, ...@@ -1862,7 +1862,24 @@ implicit_conversion (tree to, tree from, tree expr, bool c_cast_p,
cand = build_user_type_conversion_1 (to, expr, flags, complain); cand = build_user_type_conversion_1 (to, expr, flags, complain);
if (cand) if (cand)
{
if (BRACE_ENCLOSED_INITIALIZER_P (expr)
&& CONSTRUCTOR_NELTS (expr) == 1
&& !is_list_ctor (cand->fn))
{
/* "If C is not an initializer-list constructor and the
initializer list has a single element of type cv U, where U is
X or a class derived from X, the implicit conversion sequence
has Exact Match rank if U is X, or Conversion rank if U is
derived from X." */
tree elt = CONSTRUCTOR_ELT (expr, 0)->value;
tree elttype = TREE_TYPE (elt);
if (reference_related_p (to, elttype))
return implicit_conversion (to, elttype, elt,
c_cast_p, flags, complain);
}
conv = cand->second_conv; conv = cand->second_conv;
}
/* We used to try to bind a reference to a temporary here, but that /* We used to try to bind a reference to a temporary here, but that
is now handled after the recursive call to this function at the end is now handled after the recursive call to this function at the end
......
// DR 2137
// { dg-do run { target c++11 } }
// Test that an initializer_list constructor beats the copy constructor.
#include <initializer_list>
bool ok = false;
struct Q {
Q() = default;
Q(Q const&) = default;
Q(Q&&) = default;
Q(std::initializer_list<Q>) { ok = true; }
};
int main() {
Q x = Q { Q() };
if (!ok) __builtin_abort ();
}
// DR 2137
// { dg-do link { target c++11 } }
// Test that copying Q is better than converting to R.
struct Q {
Q() { }
Q(const Q&) { }
};
struct R {
R(const Q&);
};
void f(Q) { }
void f(R);
int main()
{
f({Q()});
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment