diff options
author | Jason Merrill <jason@redhat.com> | 2014-01-27 23:30:55 -0500 |
---|---|---|
committer | Jason Merrill <jason@gcc.gnu.org> | 2014-01-27 23:30:55 -0500 |
commit | f235ad118fed420d99d985b116a3c6a1d054d398 (patch) | |
tree | 6f8b29307f926663f67c12f91ddb6e52c933453e /gcc | |
parent | 30f6b7844aad824eb90adc0962a3663c73d5aa16 (diff) | |
download | gcc-f235ad118fed420d99d985b116a3c6a1d054d398.zip gcc-f235ad118fed420d99d985b116a3c6a1d054d398.tar.gz gcc-f235ad118fed420d99d985b116a3c6a1d054d398.tar.bz2 |
Core DR 1288
Core DR 1288
* call.c (reference_binding): Only elide braces if the single
element is reference-related.
From-SVN: r207164
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/cp/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/cp/call.c | 27 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp0x/initlist22.C | 10 |
3 files changed, 29 insertions, 12 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index b5693f2..707032f 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,9 @@ 2014-01-27 Jason Merrill <jason@redhat.com> + Core DR 1288 + * call.c (reference_binding): Only elide braces if the single + element is reference-related. + PR c++/58814 * typeck.c (cp_build_modify_expr): Make the RHS an rvalue before stabilizing. diff --git a/gcc/cp/call.c b/gcc/cp/call.c index 2c77973..7d6e621 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -1460,16 +1460,29 @@ reference_binding (tree rto, tree rfrom, tree expr, bool c_cast_p, int flags, if (expr && BRACE_ENCLOSED_INITIALIZER_P (expr)) { maybe_warn_cpp0x (CPP0X_INITIALIZER_LISTS); - conv = implicit_conversion (to, from, expr, c_cast_p, - flags, complain); - if (!CLASS_TYPE_P (to) - && CONSTRUCTOR_NELTS (expr) == 1) + /* DR 1288: Otherwise, if the initializer list has a single element + of type E and ... [T's] referenced type is reference-related to E, + the object or reference is initialized from that element... */ + if (CONSTRUCTOR_NELTS (expr) == 1) { - expr = CONSTRUCTOR_ELT (expr, 0)->value; - if (error_operand_p (expr)) + tree elt = CONSTRUCTOR_ELT (expr, 0)->value; + if (error_operand_p (elt)) return NULL; - from = TREE_TYPE (expr); + tree etype = TREE_TYPE (elt); + if (reference_related_p (to, etype)) + { + expr = elt; + from = etype; + goto skip; + } } + /* Otherwise, if T is a reference type, a prvalue temporary of the + type referenced by T is copy-list-initialized or + direct-list-initialized, depending on the kind of initialization + for the reference, and the reference is bound to that temporary. */ + conv = implicit_conversion (to, from, expr, c_cast_p, + flags, complain); + skip:; } if (TREE_CODE (from) == REFERENCE_TYPE) diff --git a/gcc/testsuite/g++.dg/cpp0x/initlist22.C b/gcc/testsuite/g++.dg/cpp0x/initlist22.C index f913aeb..19aefd3 100644 --- a/gcc/testsuite/g++.dg/cpp0x/initlist22.C +++ b/gcc/testsuite/g++.dg/cpp0x/initlist22.C @@ -1,4 +1,4 @@ -// Core issue 934 +// Core issue 934/1288 // { dg-options "-std=c++11" } int i; @@ -13,12 +13,12 @@ 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 +A& r7 { a }; // OK, direct-initialization +A&& r8 { a }; // { dg-error "lvalue" } binding && to lvalue 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 +B& r11 { b }; // OK, direct-initialization +B&& r12 { b }; // { dg-error "lvalue" } binding && to lvalue |