From: Paolo Carlini Date: Tue, 19 Dec 2017 22:14:59 +0000 (+0000) Subject: re PR c++/82593 (Internal compiler error: in process_init_constructor_array, at cp... X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=1c97d579f228a3ccfb2e08377eb387b904194911;p=gcc.git re PR c++/82593 (Internal compiler error: in process_init_constructor_array, at cp/typeck2.c:1294) /cp 2017-12-19 Paolo Carlini PR c++/82593 * decl.c (check_array_designated_initializer): Not static. * cp-tree.h (check_array_designated_initializer): Declare. * typeck2.c (process_init_constructor_array): Call the latter. * parser.c (cp_parser_initializer_list): Check the return value of require_potential_rvalue_constant_expression. /testsuite 2017-12-19 Paolo Carlini PR c++/82593 * g++.dg/cpp0x/desig2.C: New. * g++.dg/cpp0x/desig3.C: Likewise. * g++.dg/cpp0x/desig4.C: Likewise. From-SVN: r255845 --- diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 831cb23edd9..77e18677c4f 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,12 @@ +2017-12-19 Paolo Carlini + + PR c++/82593 + * decl.c (check_array_designated_initializer): Not static. + * cp-tree.h (check_array_designated_initializer): Declare. + * typeck2.c (process_init_constructor_array): Call the latter. + * parser.c (cp_parser_initializer_list): Check the return value + of require_potential_rvalue_constant_expression. + 2017-12-19 Martin Sebor PR c++/83394 diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 4cdbbdebde3..1a7ef9e7d0d 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -6212,6 +6212,8 @@ extern bool require_deduced_type (tree, tsubst_flags_t = tf_warning_or_error); extern tree finish_case_label (location_t, tree, tree); extern tree cxx_maybe_build_cleanup (tree, tsubst_flags_t); +extern bool check_array_designated_initializer (constructor_elt *, + unsigned HOST_WIDE_INT); /* in decl2.c */ extern void record_mangling (tree, bool); diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 453a2bd9197..cac45f25ec2 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -5308,7 +5308,7 @@ grok_reference_init (tree decl, tree type, tree init, int flags) initializer. If it does, an error is issued. Returns true if CE is valid, i.e., does not have a designated initializer. */ -static bool +bool check_array_designated_initializer (constructor_elt *ce, unsigned HOST_WIDE_INT index) { diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index e13e127d45f..35f4e367595 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -22101,8 +22101,10 @@ cp_parser_initializer_list (cp_parser* parser, bool* non_constant_p) if (!cp_parser_parse_definitely (parser)) designator = NULL_TREE; - else if (non_const) - require_potential_rvalue_constant_expression (designator); + else if (non_const + && (!require_potential_rvalue_constant_expression + (designator))) + designator = NULL_TREE; if (designator) /* Warn the user that they are using an extension. */ pedwarn (loc, OPT_Wpedantic, diff --git a/gcc/cp/typeck2.c b/gcc/cp/typeck2.c index e5bb249b2be..e54d948f69f 100644 --- a/gcc/cp/typeck2.c +++ b/gcc/cp/typeck2.c @@ -1305,17 +1305,10 @@ process_init_constructor_array (tree type, tree init, int nested, FOR_EACH_VEC_SAFE_ELT (v, i, ce) { - if (ce->index) - { - gcc_assert (TREE_CODE (ce->index) == INTEGER_CST); - if (compare_tree_int (ce->index, i) != 0) - { - ce->value = error_mark_node; - sorry ("non-trivial designated initializers not supported"); - } - } - else + if (!ce->index) ce->index = size_int (i); + else if (!check_array_designated_initializer (ce, i)) + ce->index = error_mark_node; gcc_assert (ce->value); ce->value = massage_init_elt (TREE_TYPE (type), ce->value, nested, complain); diff --git a/gcc/testsuite/g++.dg/cpp0x/desig2.C b/gcc/testsuite/g++.dg/cpp0x/desig2.C new file mode 100644 index 00000000000..5ac2d15d952 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/desig2.C @@ -0,0 +1,23 @@ +// PR c++/82593 +// { dg-do compile { target c++11 } } +// { dg-options "" } + +enum { + INDEX1 = 0, + INDEX2 +}; + +class SomeClass { +public: + SomeClass(); +private: + struct { int field; } member[2]; +}; + +SomeClass::SomeClass() + : member({ + [INDEX1] = { .field = 0 }, + [INDEX2] = { .field = 1 } + }) +{ +} diff --git a/gcc/testsuite/g++.dg/cpp0x/desig3.C b/gcc/testsuite/g++.dg/cpp0x/desig3.C new file mode 100644 index 00000000000..0a50b742d45 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/desig3.C @@ -0,0 +1,21 @@ +// PR c++/82593 +// { dg-do compile { target c++11 } } +// { dg-options "" } + +const int INDEX1 = 0; +const int INDEX2 = 1; + +class SomeClass { +public: + SomeClass(); +private: + struct { int field; } member[2]; +}; + +SomeClass::SomeClass() + : member({ + [INDEX1] = { .field = 0 }, + [INDEX2] = { .field = 1 } + }) +{ +} diff --git a/gcc/testsuite/g++.dg/cpp0x/desig4.C b/gcc/testsuite/g++.dg/cpp0x/desig4.C new file mode 100644 index 00000000000..ff88d82adc0 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/desig4.C @@ -0,0 +1,21 @@ +// PR c++/82593 +// { dg-do compile { target c++11 } } +// { dg-options "" } + +int INDEX1 = 0; +int INDEX2 = 1; + +class SomeClass { +public: + SomeClass(); +private: + struct { int field; } member[2]; +}; + +SomeClass::SomeClass() + : member({ + [INDEX1] = { .field = 0 }, // { dg-error "constant expression" } + [INDEX2] = { .field = 1 } // { dg-error "constant expression" } + }) +{ +}