aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2015-05-05 22:07:34 -0400
committerJason Merrill <jason@gcc.gnu.org>2015-05-05 22:07:34 -0400
commitb8dd691344db6be88a843242d1686e7266de631b (patch)
tree409cfc7b3a2f6dac9696531b7f57aeb84e497086 /gcc
parent99573e81e88654e318c1e07419f36fb6d50caac9 (diff)
downloadgcc-b8dd691344db6be88a843242d1686e7266de631b.zip
gcc-b8dd691344db6be88a843242d1686e7266de631b.tar.gz
gcc-b8dd691344db6be88a843242d1686e7266de631b.tar.bz2
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog13
-rw-r--r--gcc/cp/call.c28
-rw-r--r--gcc/cp/init.c1
-rw-r--r--gcc/cp/typeck2.c4
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/initlist-dr1518.C27
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/initlist40.C2
6 files changed, 56 insertions, 19 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 17c2d1d..3276b76 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,16 @@
+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>
* parser.c (cp_parser_asm_definition): Only test for
diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index 7bdf236..b77f69a 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -6243,19 +6243,9 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum,
tree convfn = cand->fn;
unsigned i;
- /* 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);
- }
-
- /* If we're initializing from {}, it's value-initialization. */
+ /* If we're initializing from {}, it's value-initialization. Note
+ that under the resolution of core 1630, value-initialization can
+ use explicit constructors. */
if (BRACE_ENCLOSED_INITIALIZER_P (expr)
&& CONSTRUCTOR_NELTS (expr) == 0
&& TYPE_HAS_DEFAULT_CONSTRUCTOR (totype))
@@ -6271,6 +6261,18 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum,
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);
/* Set user_conv_p on the argument conversions, so rvalue/base
diff --git a/gcc/cp/init.c b/gcc/cp/init.c
index a4fc9ff..c41e30c 100644
--- a/gcc/cp/init.c
+++ b/gcc/cp/init.c
@@ -3720,7 +3720,6 @@ build_vec_init (tree base, tree maxindex, tree init,
if (cxx_dialect >= cxx11 && AGGREGATE_TYPE_P (type))
{
init = build_constructor (init_list_type_node, NULL);
- CONSTRUCTOR_IS_DIRECT_INIT (init) = true;
}
else
{
diff --git a/gcc/cp/typeck2.c b/gcc/cp/typeck2.c
index c0df823..6e0c777 100644
--- a/gcc/cp/typeck2.c
+++ b/gcc/cp/typeck2.c
@@ -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
initialization explicit by list-initializing from T{}. */
next = build_constructor (init_list_type_node, NULL);
- CONSTRUCTOR_IS_DIRECT_INIT (next) = true;
next = massage_init_elt (TREE_TYPE (type), next, complain);
if (initializer_zerop (next))
/* The default zero-initialization is fine for us; don't
@@ -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
a class, just build one up; if it's an array, recurse. */
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);
/* Warn when some struct elements are implicitly initialized. */
diff --git a/gcc/testsuite/g++.dg/cpp0x/initlist-dr1518.C b/gcc/testsuite/g++.dg/cpp0x/initlist-dr1518.C
new file mode 100644
index 0000000..9f8ee0b
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/initlist-dr1518.C
@@ -0,0 +1,27 @@
+// 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({});
+}
diff --git a/gcc/testsuite/g++.dg/cpp0x/initlist40.C b/gcc/testsuite/g++.dg/cpp0x/initlist40.C
index 6e6a11a..de2e19d 100644
--- a/gcc/testsuite/g++.dg/cpp0x/initlist40.C
+++ b/gcc/testsuite/g++.dg/cpp0x/initlist40.C
@@ -8,6 +8,6 @@ struct A
int main()
{
- A a1 = { }; // { dg-error "explicit" }
+ A a1 = { };
A a2 = { 24 }; // { dg-error "explicit" }
}