re PR c++/48281 ([C++0x] internal compiler error: in record_reference, at cgraphbuild...
authorJason Merrill <jason@redhat.com>
Wed, 30 Mar 2011 18:07:09 +0000 (14:07 -0400)
committerJason Merrill <jason@gcc.gnu.org>
Wed, 30 Mar 2011 18:07:09 +0000 (14:07 -0400)
PR c++/48281
* semantics.c (finish_compound_literal): Do put static/constant
arrays in static variables.

From-SVN: r171741

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

index 1b96aa4e460ce9630280a2700248c34dfc614253..75f7da727a4717f9ca5bf00b958b3e64fc09654f 100644 (file)
@@ -1,5 +1,9 @@
 2011-03-30  Jason Merrill  <jason@redhat.com>
 
+       PR c++/48281
+       * semantics.c (finish_compound_literal): Do put static/constant
+       arrays in static variables.
+
        * call.c (convert_like_real) [ck_list]: Build up the
        initializer_list object directly.
        * decl.c (build_init_list_var_init): Adjust.
index 5a659434de68979619c340cf0e3dd7064314c84d..74e9a9f5a6f12ce39afc48a405b84fedb9280635 100644 (file)
@@ -2335,7 +2335,34 @@ finish_compound_literal (tree type, tree compound_literal)
   if (TREE_CODE (type) == ARRAY_TYPE)
     cp_complete_array_type (&type, compound_literal, false);
   compound_literal = digest_init (type, compound_literal);
-  return get_target_expr (compound_literal);
+  /* Put static/constant array temporaries in static variables, but always
+     represent class temporaries with TARGET_EXPR so we elide copies.  */
+  if ((!at_function_scope_p () || CP_TYPE_CONST_P (type))
+      && TREE_CODE (type) == ARRAY_TYPE
+      && initializer_constant_valid_p (compound_literal, type))
+    {
+      tree decl = create_temporary_var (type);
+      DECL_INITIAL (decl) = compound_literal;
+      TREE_STATIC (decl) = 1;
+      if (literal_type_p (type) && CP_TYPE_CONST_NON_VOLATILE_P (type))
+       {
+         /* 5.19 says that a constant expression can include an
+            lvalue-rvalue conversion applied to "a glvalue of literal type
+            that refers to a non-volatile temporary object initialized
+            with a constant expression".  Rather than try to communicate
+            that this VAR_DECL is a temporary, just mark it constexpr.  */
+         DECL_DECLARED_CONSTEXPR_P (decl) = true;
+         DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (decl) = true;
+         TREE_CONSTANT (decl) = true;
+       }
+      cp_apply_type_quals_to_decl (cp_type_quals (type), decl);
+      decl = pushdecl_top_level (decl);
+      DECL_NAME (decl) = make_anon_name ();
+      SET_DECL_ASSEMBLER_NAME (decl, DECL_NAME (decl));
+      return decl;
+    }
+  else
+    return get_target_expr (compound_literal);
 }
 
 /* Return the declaration for the function-name variable indicated by
index be3a9299b3c8b6767a21f8ecfa29fa0aee7bc188..6ec96c906fb94bfba4325268ca57ec8ce9359998 100644 (file)
@@ -1,3 +1,7 @@
+2011-03-30  Jason Merrill  <jason@redhat.com>
+
+       * g++.dg/cpp0x/initlist46.C: New.
+
 2011-03-30  Richard Sandiford  <richard.sandiford@linaro.org>
 
        PR target/47551
diff --git a/gcc/testsuite/g++.dg/cpp0x/initlist46.C b/gcc/testsuite/g++.dg/cpp0x/initlist46.C
new file mode 100644 (file)
index 0000000..2b9f07d
--- /dev/null
@@ -0,0 +1,14 @@
+// PR c++/48281
+// { dg-options "-std=c++0x -O2" }
+// { dg-do run }
+
+#include <initializer_list>
+
+typedef std::initializer_list<int>  int1;
+typedef std::initializer_list<int1> int2;
+static int2 ib = {{42,2,3,4,5},{2,3,4,5,1},{3,4,5,2,1}};
+
+int main()
+{
+  return *(ib.begin()->begin()) != 42;
+}