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>
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.
(cxx_eval_loop_expr): Handle COMPOUND_EXPR body.
(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,
cand = build_user_type_conversion_1 (to, expr, flags, complain);
if (cand)
conv = cand->second_conv;
{
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;
}
/* 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
......
// 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