aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2011-03-30 14:07:09 -0400
committerJason Merrill <jason@gcc.gnu.org>2011-03-30 14:07:09 -0400
commita63940ba494c733b84fae4821a71d2f4b8bec0b8 (patch)
treef09963879d8722ec5295e87c4327d9a3283792eb /gcc
parent88d37ae679fd5fd498076514d16248ccb5b2b8ae (diff)
downloadgcc-a63940ba494c733b84fae4821a71d2f4b8bec0b8.zip
gcc-a63940ba494c733b84fae4821a71d2f4b8bec0b8.tar.gz
gcc-a63940ba494c733b84fae4821a71d2f4b8bec0b8.tar.bz2
re PR c++/48281 ([C++0x] internal compiler error: in record_reference, at cgraphbuild.c:60)
PR c++/48281 * semantics.c (finish_compound_literal): Do put static/constant arrays in static variables. From-SVN: r171741
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog4
-rw-r--r--gcc/cp/semantics.c29
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/initlist46.C14
4 files changed, 50 insertions, 1 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 1b96aa4..75f7da7 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -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.
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index 5a65943..74e9a9f5 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -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
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index be3a929..6ec96c9 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
index 0000000..2b9f07d
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/initlist46.C
@@ -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;
+}