From fe7eb484d309fefb7366b3838900e632da9dd234 Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Mon, 20 Jun 2011 22:24:17 -0400 Subject: [PATCH] re PR c++/49216 ([C++0x] ICE on compiling new-expression with braced-init-list for arrays) PR c++/49216 * init.c (build_vec_init): Don't try to use a CONSTRUCTOR when base is a pointer. * typeck2.c (process_init_constructor_array): Use {} for classes, too. * call.c (convert_like_real): Handle substitution failure. From-SVN: r175237 --- gcc/cp/ChangeLog | 7 +++++++ gcc/cp/call.c | 2 +- gcc/cp/init.c | 5 +++-- gcc/cp/typeck2.c | 11 +++-------- gcc/testsuite/ChangeLog | 5 +++++ gcc/testsuite/g++.dg/cpp0x/initlist53.C | 20 ++++++++++++++++++++ 6 files changed, 39 insertions(+), 11 deletions(-) create mode 100644 gcc/testsuite/g++.dg/cpp0x/initlist53.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 6b84111ae1a..a48f9c5a6b7 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,12 @@ 2011-06-20 Jason Merrill + PR c++/49216 + * init.c (build_vec_init): Don't try to use a CONSTRUCTOR when + base is a pointer. + * typeck2.c (process_init_constructor_array): Use {} for classes, + too. + * call.c (convert_like_real): Handle substitution failure. + PR c++/48138 * pt.c (canonicalize_type_argument): New. (convert_template_argument, unify): Use it. diff --git a/gcc/cp/call.c b/gcc/cp/call.c index e9d6e7ea354..caf95b077ce 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -5621,7 +5621,7 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum, expr = build_cplus_new (totype, expr, complain); /* Remember that this was list-initialization. */ - if (convs->check_narrowing) + if (convs->check_narrowing && expr != error_mark_node) TARGET_EXPR_LIST_INIT_P (expr) = true; } diff --git a/gcc/cp/init.c b/gcc/cp/init.c index 140e064b659..3c347a4521f 100644 --- a/gcc/cp/init.c +++ b/gcc/cp/init.c @@ -3082,8 +3082,9 @@ build_vec_init (tree base, tree maxindex, tree init, unsigned HOST_WIDE_INT idx; tree field, elt; /* Should we try to create a constant initializer? */ - bool try_const = (literal_type_p (inner_elt_type) - || TYPE_HAS_CONSTEXPR_CTOR (inner_elt_type)); + bool try_const = (TREE_CODE (atype) == ARRAY_TYPE + && (literal_type_p (inner_elt_type) + || TYPE_HAS_CONSTEXPR_CTOR (inner_elt_type))); bool saw_non_const = false; bool saw_const = false; /* If we're initializing a static array, we want to do static diff --git a/gcc/cp/typeck2.c b/gcc/cp/typeck2.c index 6d6267e8d72..ff2949c510d 100644 --- a/gcc/cp/typeck2.c +++ b/gcc/cp/typeck2.c @@ -1051,14 +1051,9 @@ process_init_constructor_array (tree type, tree init, if (type_build_ctor_call (TREE_TYPE (type))) { /* If this type needs constructors run for default-initialization, - we can't rely on the back end to do it 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. */ - if (MAYBE_CLASS_TYPE_P (TREE_TYPE (type))) - next = build_functional_cast (TREE_TYPE (type), NULL_TREE, - complain); - else - next = build_constructor (init_list_type_node, NULL); + we can't rely on the back end to do it for us, so make the + initialization explicit by list-initializing from {}. */ + next = build_constructor (init_list_type_node, NULL); next = digest_init (TREE_TYPE (type), next, complain); } else if (!zero_init_p (TREE_TYPE (type))) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index f18487f74b4..3da23b1bf84 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2011-06-20 Jason Merrill + + PR c++/49216 + * g++.dg/cpp0x/initlist53.C: New. + 2011-06-20 Tobias Burnus PR fortran/18918 diff --git a/gcc/testsuite/g++.dg/cpp0x/initlist53.C b/gcc/testsuite/g++.dg/cpp0x/initlist53.C new file mode 100644 index 00000000000..750ebbacb96 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/initlist53.C @@ -0,0 +1,20 @@ +// PR c++/49216 +// { dg-options -std=c++0x } +// { dg-do run } + +#include +extern "C" void abort(); + +bool constructed; + +struct A +{ + A(std::initializer_list) { constructed = true; } +}; + +int main() { + new A[1]{}; + int *p = new int[1]{}; + if (p[0] != 0 || !constructed) + abort(); +} -- 2.30.2