aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2009-07-21 23:32:30 -0400
committerJason Merrill <jason@gcc.gnu.org>2009-07-21 23:32:30 -0400
commitbd1f11bec9a0ada1f267a62dbb6c29e242141cd4 (patch)
tree76a85593349333fc713e0b713267805df1ca478c
parentd0b7964a488cebaf4b1f82eb3367fad2613cb1a8 (diff)
downloadgcc-bd1f11bec9a0ada1f267a62dbb6c29e242141cd4.zip
gcc-bd1f11bec9a0ada1f267a62dbb6c29e242141cd4.tar.gz
gcc-bd1f11bec9a0ada1f267a62dbb6c29e242141cd4.tar.bz2
Core issue 934
Core issue 934 * call.c (reference_binding): Implement binding to { }. (initialize_reference): Binding temporary to non-const && is fine. * decl.c (grok_reference_init): Remove error for CONSTRUCTOR. From-SVN: r149873
-rw-r--r--gcc/cp/ChangeLog7
-rw-r--r--gcc/cp/call.c22
-rw-r--r--gcc/cp/decl.c7
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/initlist22.C24
-rw-r--r--gcc/testsuite/g++.old-deja/g++.brendan/init4.C2
6 files changed, 56 insertions, 11 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 520ae54..86f8b50 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,10 @@
+2009-07-21 Jason Merrill <jason@redhat.com>
+
+ Core issue 934
+ * call.c (reference_binding): Implement binding to { }.
+ (initialize_reference): Binding temporary to non-const && is fine.
+ * decl.c (grok_reference_init): Remove error for CONSTRUCTOR.
+
2009-07-17 Richard Guenther <rguenther@suse.de>
PR c/40401
diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index f4b5b02..845fa56 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -1221,7 +1221,21 @@ reference_binding (tree rto, tree rfrom, tree expr, bool c_cast_p, int flags)
lvalue_p = clk_ordinary;
from = TREE_TYPE (from);
}
- else if (expr)
+
+ if (expr && BRACE_ENCLOSED_INITIALIZER_P (expr))
+ {
+ maybe_warn_cpp0x ("extended initializer lists");
+ conv = implicit_conversion (to, from, expr, c_cast_p,
+ flags);
+ if (!CLASS_TYPE_P (to)
+ && CONSTRUCTOR_NELTS (expr) == 1)
+ {
+ expr = CONSTRUCTOR_ELT (expr, 0)->value;
+ from = TREE_TYPE (expr);
+ }
+ }
+
+ if (lvalue_p == clk_none && expr)
lvalue_p = real_lvalue_p (expr);
tfrom = from;
@@ -1363,8 +1377,9 @@ reference_binding (tree rto, tree rfrom, tree expr, bool c_cast_p, int flags)
if (!(flags & LOOKUP_COPY_PARM))
flags |= LOOKUP_ONLYCONVERTING;
- conv = implicit_conversion (to, from, expr, c_cast_p,
- flags);
+ if (!conv)
+ conv = implicit_conversion (to, from, expr, c_cast_p,
+ flags);
if (!conv)
return NULL;
@@ -7541,6 +7556,7 @@ initialize_reference (tree type, tree expr, tree decl, tree *cleanup)
if (!conv || conv->bad_p)
{
if (!(TYPE_QUALS (TREE_TYPE (type)) & TYPE_QUAL_CONST)
+ && !TYPE_REF_IS_RVALUE (type)
&& !real_lvalue_p (expr))
error ("invalid initialization of non-const reference of "
"type %qT from a temporary of type %qT",
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 251d0a3..6fa9428 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -4370,13 +4370,6 @@ grok_reference_init (tree decl, tree type, tree init, tree *cleanup)
return NULL_TREE;
}
- if (TREE_CODE (init) == CONSTRUCTOR)
- {
- error ("ISO C++ forbids use of initializer list to "
- "initialize reference %qD", decl);
- return NULL_TREE;
- }
-
if (TREE_CODE (init) == TREE_LIST)
init = build_x_compound_expr_from_list (init, "initializer");
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index ed0b13a..d007c46 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2009-07-21 Jason Merrill <jason@redhat.com>
+
+ Core issue 934
+ * g++.dg/cpp0x/initlist22.C: New.
+
2009-07-21 Uros Bizjak <ubizjak@gmail.com>
* gcc.target/i386/vectorize8.c: New test.
diff --git a/gcc/testsuite/g++.dg/cpp0x/initlist22.C b/gcc/testsuite/g++.dg/cpp0x/initlist22.C
new file mode 100644
index 0000000..bf1c554
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/initlist22.C
@@ -0,0 +1,24 @@
+// Core issue 934
+// { dg-options "-std=c++0x" }
+
+int i;
+
+int& r1{ i }; // OK, direct binding
+int&& r2{ i }; // OK, direct binding
+
+int& r3{ }; // { dg-error "" } reference to temporary
+int&& r4{ }; // OK, reference to temporary
+
+struct A { int i; } a;
+
+A& r5 { i }; // { dg-error "" } reference to temporary
+A&& r6 { i }; // OK, aggregate initialization of temporary
+A& r7 { a }; // { dg-error "" } invalid aggregate initializer for A
+A&& r8 { a }; // { dg-error "" } invalid aggregate initializer for A
+
+struct B { B(int); int i; } b(0);
+
+B& r9 { i }; // { dg-error "" } reference to temporary
+B&& r10 { i }; // OK, make temporary with B(int) constructor
+B& r11 { b }; // { dg-error "" } reference to temporary
+B&& r12 { b }; // OK, make temporary with copy constructor
diff --git a/gcc/testsuite/g++.old-deja/g++.brendan/init4.C b/gcc/testsuite/g++.old-deja/g++.brendan/init4.C
index 71e7cd6..aa2bfb6 100644
--- a/gcc/testsuite/g++.old-deja/g++.brendan/init4.C
+++ b/gcc/testsuite/g++.old-deja/g++.brendan/init4.C
@@ -2,4 +2,4 @@
// GROUPS passed initialization
struct CharList { int i; };
-const CharList& terminals = { 1 };// { dg-error "" } .*
+const CharList& terminals = { 1 }; // { dg-error "initializer lists" } c++0x