re PR c++/64029 (const int (&in)[]{1,2,3,4,5}; results in internal compiler error...
authorJason Merrill <jason@redhat.com>
Thu, 4 Dec 2014 20:37:30 +0000 (15:37 -0500)
committerJason Merrill <jason@gcc.gnu.org>
Thu, 4 Dec 2014 20:37:30 +0000 (15:37 -0500)
PR c++/64029
* decl.c (grok_reference_init): Complete array type.

From-SVN: r218402

gcc/cp/ChangeLog
gcc/cp/decl.c
gcc/testsuite/g++.dg/cpp0x/initlist89.C [new file with mode: 0644]

index 2db8bd7c581825d1c373ffedb489a13911717e12..361e634ea5f6e6efcce085529bf182e37016cef0 100644 (file)
@@ -1,5 +1,8 @@
 2014-12-03  Jason Merrill  <jason@redhat.com>
 
+       PR c++/64029
+       * decl.c (grok_reference_init): Complete array type.
+
        PR c++/64080
        * constexpr.c (cxx_eval_store_expression): Handle non-decl store
        targets.
index 2996ee68757c1ff4f95ea42bee1dd559e5d3f985..5639b3d54c80b27dcc17d1b28e4370c3214fc0e9 100644 (file)
@@ -4936,11 +4936,26 @@ grok_reference_init (tree decl, tree type, tree init, int flags)
     init = build_x_compound_expr_from_list (init, ELK_INIT,
                                            tf_warning_or_error);
 
-  if (TREE_CODE (TREE_TYPE (type)) != ARRAY_TYPE
+  tree ttype = TREE_TYPE (type);
+  if (TREE_CODE (ttype) != ARRAY_TYPE
       && TREE_CODE (TREE_TYPE (init)) == ARRAY_TYPE)
     /* Note: default conversion is only called in very special cases.  */
     init = decay_conversion (init, tf_warning_or_error);
 
+  /* check_initializer handles this for non-reference variables, but for
+     references we need to do it here or the initializer will get the
+     incomplete array type and confuse later calls to
+     cp_complete_array_type.  */
+  if (TREE_CODE (ttype) == ARRAY_TYPE
+      && TYPE_DOMAIN (ttype) == NULL_TREE
+      && (BRACE_ENCLOSED_INITIALIZER_P (init)
+         || TREE_CODE (init) == STRING_CST))
+    {
+      cp_complete_array_type (&ttype, init, false);
+      if (ttype != TREE_TYPE (type))
+       type = cp_build_reference_type (ttype, TYPE_REF_IS_RVALUE (type));
+    }
+
   /* Convert INIT to the reference type TYPE.  This may involve the
      creation of a temporary, whose lifetime must be the same as that
      of the reference.  If so, a DECL_EXPR for the temporary will be
diff --git a/gcc/testsuite/g++.dg/cpp0x/initlist89.C b/gcc/testsuite/g++.dg/cpp0x/initlist89.C
new file mode 100644 (file)
index 0000000..e221664
--- /dev/null
@@ -0,0 +1,4 @@
+// PR c++/64029
+// { dg-do compile { target c++11 } }
+
+const int (&in)[]{1,2,3,4,5};