re PR c++/82593 (Internal compiler error: in process_init_constructor_array, at cp...
authorPaolo Carlini <paolo.carlini@oracle.com>
Tue, 19 Dec 2017 22:14:59 +0000 (22:14 +0000)
committerPaolo Carlini <paolo@gcc.gnu.org>
Tue, 19 Dec 2017 22:14:59 +0000 (22:14 +0000)
/cp
2017-12-19  Paolo Carlini  <paolo.carlini@oracle.com>

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  <paolo.carlini@oracle.com>

PR c++/82593
* g++.dg/cpp0x/desig2.C: New.
* g++.dg/cpp0x/desig3.C: Likewise.
* g++.dg/cpp0x/desig4.C: Likewise.

From-SVN: r255845

gcc/cp/ChangeLog
gcc/cp/cp-tree.h
gcc/cp/decl.c
gcc/cp/parser.c
gcc/cp/typeck2.c
gcc/testsuite/g++.dg/cpp0x/desig2.C [new file with mode: 0644]
gcc/testsuite/g++.dg/cpp0x/desig3.C [new file with mode: 0644]
gcc/testsuite/g++.dg/cpp0x/desig4.C [new file with mode: 0644]

index 831cb23edd902f899219ed871cb7f0dff3faf35a..77e18677c4fc8d2fd9eaccb4a2e875c78bef5c87 100644 (file)
@@ -1,3 +1,12 @@
+2017-12-19  Paolo Carlini  <paolo.carlini@oracle.com>
+
+       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  <msebor@redhat.com>
 
        PR c++/83394
index 4cdbbdebde385c97e556711f44aeb927a8bf8f1d..1a7ef9e7d0d56a5788c43c1ac88445312511caea 100644 (file)
@@ -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);
index 453a2bd91970855de8ac1a947995be80ad99d750..cac45f25ec2bbf479d8d5735ed21d23ba28957d1 100644 (file)
@@ -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)
 {
index e13e127d45fefe30874305c2f91b0d39f1a61bdd..35f4e367595a7b8be3076a6b9e864e3818ada25f 100644 (file)
@@ -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,
index e5bb249b2be6eabafdd6b4de6330c427565fde6b..e54d948f69fa2624b48e44bbda6b9a2b772ab073 100644 (file)
@@ -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 (file)
index 0000000..5ac2d15
--- /dev/null
@@ -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 (file)
index 0000000..0a50b74
--- /dev/null
@@ -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 (file)
index 0000000..ff88d82
--- /dev/null
@@ -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" }
+ })
+{
+}