Commit b8dd6913 by Jason Merrill Committed by Jason Merrill

DR 1518 DR 1630 PR c++/54835 PR c++/60417

	DR 1518
	DR 1630
	PR c++/54835
	PR c++/60417
	* call.c (convert_like_real): Check value-initialization before
	explicit.
	* typeck2.c (process_init_constructor_record): Don't set
	CONSTRUCTOR_IS_DIRECT_INIT.
	(process_init_constructor_array): Likewise.
	* init.c (build_vec_init): Likewise.

From-SVN: r222836
parent 99573e81
2015-05-05 Jason Merrill <jason@redhat.com>
DR 1518
DR 1630
PR c++/54835
PR c++/60417
* call.c (convert_like_real): Check value-initialization before
explicit.
* typeck2.c (process_init_constructor_record): Don't set
CONSTRUCTOR_IS_DIRECT_INIT.
(process_init_constructor_array): Likewise.
* init.c (build_vec_init): Likewise.
2015-05-05 David Malcolm <dmalcolm@redhat.com> 2015-05-05 David Malcolm <dmalcolm@redhat.com>
* parser.c (cp_parser_asm_definition): Only test for * parser.c (cp_parser_asm_definition): Only test for
......
...@@ -6243,19 +6243,9 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum, ...@@ -6243,19 +6243,9 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum,
tree convfn = cand->fn; tree convfn = cand->fn;
unsigned i; unsigned i;
/* When converting from an init list we consider explicit /* If we're initializing from {}, it's value-initialization. Note
constructors, but actually trying to call one is an error. */ that under the resolution of core 1630, value-initialization can
if (DECL_NONCONVERTING_P (convfn) && DECL_CONSTRUCTOR_P (convfn) use explicit constructors. */
/* Unless this is for direct-list-initialization. */
&& !DIRECT_LIST_INIT_P (expr))
{
if (!(complain & tf_error))
return error_mark_node;
error ("converting to %qT from initializer list would use "
"explicit constructor %qD", totype, convfn);
}
/* If we're initializing from {}, it's value-initialization. */
if (BRACE_ENCLOSED_INITIALIZER_P (expr) if (BRACE_ENCLOSED_INITIALIZER_P (expr)
&& CONSTRUCTOR_NELTS (expr) == 0 && CONSTRUCTOR_NELTS (expr) == 0
&& TYPE_HAS_DEFAULT_CONSTRUCTOR (totype)) && TYPE_HAS_DEFAULT_CONSTRUCTOR (totype))
...@@ -6271,6 +6261,18 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum, ...@@ -6271,6 +6261,18 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum,
return expr; return expr;
} }
/* When converting from an init list we consider explicit
constructors, but actually trying to call one is an error. */
if (DECL_NONCONVERTING_P (convfn) && DECL_CONSTRUCTOR_P (convfn)
/* Unless this is for direct-list-initialization. */
&& !DIRECT_LIST_INIT_P (expr))
{
if (!(complain & tf_error))
return error_mark_node;
error ("converting to %qT from initializer list would use "
"explicit constructor %qD", totype, convfn);
}
expr = mark_rvalue_use (expr); expr = mark_rvalue_use (expr);
/* Set user_conv_p on the argument conversions, so rvalue/base /* Set user_conv_p on the argument conversions, so rvalue/base
......
...@@ -3720,7 +3720,6 @@ build_vec_init (tree base, tree maxindex, tree init, ...@@ -3720,7 +3720,6 @@ build_vec_init (tree base, tree maxindex, tree init,
if (cxx_dialect >= cxx11 && AGGREGATE_TYPE_P (type)) if (cxx_dialect >= cxx11 && AGGREGATE_TYPE_P (type))
{ {
init = build_constructor (init_list_type_node, NULL); init = build_constructor (init_list_type_node, NULL);
CONSTRUCTOR_IS_DIRECT_INIT (init) = true;
} }
else else
{ {
......
...@@ -1285,7 +1285,6 @@ process_init_constructor_array (tree type, tree init, ...@@ -1285,7 +1285,6 @@ process_init_constructor_array (tree type, tree init,
we can't rely on the back end to do it for us, so make the we can't rely on the back end to do it for us, so make the
initialization explicit by list-initializing from T{}. */ initialization explicit by list-initializing from T{}. */
next = build_constructor (init_list_type_node, NULL); next = build_constructor (init_list_type_node, NULL);
CONSTRUCTOR_IS_DIRECT_INIT (next) = true;
next = massage_init_elt (TREE_TYPE (type), next, complain); next = massage_init_elt (TREE_TYPE (type), next, complain);
if (initializer_zerop (next)) if (initializer_zerop (next))
/* The default zero-initialization is fine for us; don't /* The default zero-initialization is fine for us; don't
...@@ -1396,9 +1395,6 @@ process_init_constructor_record (tree type, tree init, ...@@ -1396,9 +1395,6 @@ process_init_constructor_record (tree type, tree init,
for us, so build up TARGET_EXPRs. If the type in question is for us, so build up TARGET_EXPRs. If the type in question is
a class, just build one up; if it's an array, recurse. */ a class, just build one up; if it's an array, recurse. */
next = build_constructor (init_list_type_node, NULL); next = build_constructor (init_list_type_node, NULL);
/* Call this direct-initialization pending DR 1518 resolution so
that explicit default ctors don't break valid C++03 code. */
CONSTRUCTOR_IS_DIRECT_INIT (next) = true;
next = massage_init_elt (TREE_TYPE (field), next, complain); next = massage_init_elt (TREE_TYPE (field), next, complain);
/* Warn when some struct elements are implicitly initialized. */ /* Warn when some struct elements are implicitly initialized. */
......
// DR 1518
// { dg-do compile { target c++11 } }
struct A {
explicit A() = default;
};
struct B : A {
explicit B() = default;
};
struct C {
explicit C();
};
struct D : A {
C c;
explicit D() = default;
};
template<typename T> void f() {
T t = {};
}
template<typename T> void g() {
void x(T t);
x({});
}
...@@ -8,6 +8,6 @@ struct A ...@@ -8,6 +8,6 @@ struct A
int main() int main()
{ {
A a1 = { }; // { dg-error "explicit" } A a1 = { };
A a2 = { 24 }; // { dg-error "explicit" } A a2 = { 24 }; // { dg-error "explicit" }
} }
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