Jason suggested that the way forward with this PR, where we ICE because we have
a default mem-initializer for a flexible array, and verify_ctor_sanity crashes
on that, is to reject such code.  This patch attempts to do that; I'm not
entirely happy about the placement of the maybe_reject_flexarray_init call,
but it probably couldn't be in digest_nsdmi_init, becase that could result
in multiple error messages for the same thing.

Bootstrapped/regtested on x86_64-linux, ok for trunk?

2017-02-21  Marek Polacek  <pola...@redhat.com>

        PR c++/79535
        * cp-tree.h (maybe_reject_flexarray_init): Declare.
        * init.c (maybe_reject_flexarray_init): No longer static.
        Add check for current_function_decl.
        * parser.c (cp_parser_late_parse_one_default_arg): Reject
        a default mem-initializer for a flexible array.

        * g++.dg/ext/flexary23.C: New test.

diff --git gcc/cp/cp-tree.h gcc/cp/cp-tree.h
index 6675ee5..f53f744 100644
--- gcc/cp/cp-tree.h
+++ gcc/cp/cp-tree.h
@@ -6069,6 +6069,7 @@ extern tree scalar_constant_value         (tree);
 extern tree decl_really_constant_value         (tree);
 extern int diagnose_uninitialized_cst_or_ref_member (tree, bool, bool);
 extern tree build_vtbl_address                  (tree);
+extern bool maybe_reject_flexarray_init                (tree, tree);
 
 /* in lex.c */
 extern void cxx_dup_lang_specific_decl         (tree);
diff --git gcc/cp/init.c gcc/cp/init.c
index fa74226..13ade8a 100644
--- gcc/cp/init.c
+++ gcc/cp/init.c
@@ -600,7 +600,7 @@ get_nsdmi (tree member, bool in_ctor)
 /* Diagnose the flexible array MEMBER if its INITializer is non-null
    and return true if so.  Otherwise return false.  */
 
-static bool
+bool
 maybe_reject_flexarray_init (tree member, tree init)
 {
   tree type = TREE_TYPE (member);
@@ -615,6 +615,7 @@ maybe_reject_flexarray_init (tree member, tree init)
      initializer list.  */
   location_t loc;
   if (DECL_INITIAL (member) == init
+      || !current_function_decl
       || DECL_DEFAULTED_FN (current_function_decl))
     loc = DECL_SOURCE_LOCATION (member);
   else
diff --git gcc/cp/parser.c gcc/cp/parser.c
index 0146596..15e09f7 100644
--- gcc/cp/parser.c
+++ gcc/cp/parser.c
@@ -27228,6 +27228,8 @@ cp_parser_late_parse_one_default_arg (cp_parser 
*parser, tree decl,
       if (TREE_CODE (decl) == PARM_DECL)
        parsed_arg = check_default_argument (parmtype, parsed_arg,
                                             tf_warning_or_error);
+      else if (maybe_reject_flexarray_init (decl, parsed_arg))
+       parsed_arg = error_mark_node;
       else
        parsed_arg = digest_nsdmi_init (decl, parsed_arg);
     }
diff --git gcc/testsuite/g++.dg/ext/flexary23.C 
gcc/testsuite/g++.dg/ext/flexary23.C
index e69de29..099e7fd 100644
--- gcc/testsuite/g++.dg/ext/flexary23.C
+++ gcc/testsuite/g++.dg/ext/flexary23.C
@@ -0,0 +1,11 @@
+// PR c++/79535 - ICE with NSDMI and array
+// { dg-do compile { target c++14 } }
+// { dg-options -Wno-pedantic }
+
+struct A
+{
+  int b = 1;
+  int c = 2;
+  int x[] = { c, 3 }; // { dg-error "initializer for flexible array member" }
+};
+A a = { 4, 5 };

        Marek

Reply via email to