mirror of git://gcc.gnu.org/git/gcc.git
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
This commit is contained in:
parent
06ec22b7f6
commit
218e9dde70
|
|
@ -1,5 +1,10 @@
|
||||||
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,
|
||||||
|
|
||||||
cand = build_user_type_conversion_1 (to, expr, flags, complain);
|
cand = build_user_type_conversion_1 (to, expr, flags, complain);
|
||||||
if (cand)
|
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
|
/* 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
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,20 @@
|
||||||
|
// 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 ();
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,21 @@
|
||||||
|
// 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()});
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue