diff options
author | Jason Merrill <jason@redhat.com> | 2020-02-04 14:21:59 -0500 |
---|---|---|
committer | Jason Merrill <jason@redhat.com> | 2020-02-04 14:49:19 -0500 |
commit | a1c9c9ff06ab15e697d5bac6ea6e5da2df840cf5 (patch) | |
tree | af34dc70a827bcd8d370e55e2834c5d90c5f8446 /gcc/cp/init.c | |
parent | c422cec54a5495f6f42b80f35a11c5508fe8eec3 (diff) | |
download | gcc-a1c9c9ff06ab15e697d5bac6ea6e5da2df840cf5.zip gcc-a1c9c9ff06ab15e697d5bac6ea6e5da2df840cf5.tar.gz gcc-a1c9c9ff06ab15e697d5bac6ea6e5da2df840cf5.tar.bz2 |
c++: Fix ({ ... }) array mem-initializer.
Here, we were going down the wrong path in perform_member_init because of
the incorrect parens around the mem-initializer for the array. And then
cxx_eval_vec_init_1 didn't know what to do with a CONSTRUCTOR as the
initializer. The latter issue was a straightforward fix, but I also wanted
to fix us silently accepting the parens, which led to factoring out handling
of TREE_LIST and flexarrays. The latter led to adjusting the expected
behavior on flexary29.C: we should complain about the initializer, but not
complain about a missing initializer.
As I commented on PR 92812, in this process I noticed that we weren't
handling C++20 parenthesized aggregate initialization as a mem-initializer.
So my TREE_LIST handling includes a commented out section that should
probably be part of a future fix for that issue; with it uncommented we
continue to crash on the testcase in C++20 mode, but should instead complain
about the braced-init-list not being a valid initializer for an A.
PR c++/86917
* init.c (perform_member_init): Simplify.
* constexpr.c (cx_check_missing_mem_inits): Allow uninitialized
flexarray.
(cxx_eval_vec_init_1): Handle CONSTRUCTOR.
Diffstat (limited to 'gcc/cp/init.c')
-rw-r--r-- | gcc/cp/init.c | 48 |
1 files changed, 14 insertions, 34 deletions
diff --git a/gcc/cp/init.c b/gcc/cp/init.c index 543d127..625062b 100644 --- a/gcc/cp/init.c +++ b/gcc/cp/init.c @@ -801,6 +801,17 @@ perform_member_init (tree member, tree init) member); } + if (maybe_reject_flexarray_init (member, init)) + return; + + if (init && TREE_CODE (init) == TREE_LIST + && (DIRECT_LIST_INIT_P (TREE_VALUE (init)) + /* FIXME C++20 parenthesized aggregate init (PR 92812). */ + || !(/* cxx_dialect >= cxx2a ? CP_AGGREGATE_TYPE_P (type) */ + /* : */CLASS_TYPE_P (type)))) + init = build_x_compound_expr_from_list (init, ELK_MEM_INIT, + tf_warning_or_error); + if (init == void_type_node) { /* mem() means value-initialization. */ @@ -832,12 +843,7 @@ perform_member_init (tree member, tree init) } else if (init && (TYPE_REF_P (type) - /* Pre-digested NSDMI. */ - || (((TREE_CODE (init) == CONSTRUCTOR - && TREE_TYPE (init) == type) - /* { } mem-initializer. */ - || (TREE_CODE (init) == TREE_LIST - && DIRECT_LIST_INIT_P (TREE_VALUE (init)))) + || (TREE_CODE (init) == CONSTRUCTOR && (CP_AGGREGATE_TYPE_P (type) || is_std_init_list (type))))) { @@ -847,10 +853,7 @@ perform_member_init (tree member, tree init) persists until the constructor exits." */ unsigned i; tree t; releasing_vec cleanups; - if (TREE_CODE (init) == TREE_LIST) - init = build_x_compound_expr_from_list (init, ELK_MEM_INIT, - tf_warning_or_error); - if (TREE_TYPE (init) != type) + if (!same_type_ignoring_top_level_qualifiers_p (TREE_TYPE (init), type)) { if (BRACE_ENCLOSED_INITIALIZER_P (init) && CP_AGGREGATE_TYPE_P (type)) @@ -876,23 +879,6 @@ perform_member_init (tree member, tree init) { if (TREE_CODE (type) == ARRAY_TYPE) { - if (init) - { - /* Check to make sure the member initializer is valid and - something like a CONSTRUCTOR in: T a[] = { 1, 2 } and - if it isn't, return early to avoid triggering another - error below. */ - if (maybe_reject_flexarray_init (member, init)) - return; - - if (TREE_CODE (init) != TREE_LIST || TREE_CHAIN (init)) - init = error_mark_node; - else - init = TREE_VALUE (init); - - if (BRACE_ENCLOSED_INITIALIZER_P (init)) - init = digest_init (type, init, tf_warning_or_error); - } if (init == NULL_TREE || same_type_ignoring_top_level_qualifiers_p (type, TREE_TYPE (init))) @@ -962,16 +948,10 @@ perform_member_init (tree member, tree init) /*using_new=*/false, /*complain=*/true); } - else if (TREE_CODE (init) == TREE_LIST) - /* There was an explicit member initialization. Do some work - in that case. */ - init = build_x_compound_expr_from_list (init, ELK_MEM_INIT, - tf_warning_or_error); maybe_warn_list_ctor (member, init); - /* Reject a member initializer for a flexible array member. */ - if (init && !maybe_reject_flexarray_init (member, init)) + if (init) finish_expr_stmt (cp_build_modify_expr (input_location, decl, INIT_EXPR, init, tf_warning_or_error)); |