aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2016-10-05 18:58:55 -0400
committerJason Merrill <jason@gcc.gnu.org>2016-10-05 18:58:55 -0400
commit5794b9f622dce668aa92ebabdf26abd0e799c665 (patch)
tree9101b48cac6d3d7f4e174a7b225fb708e645bc23 /gcc
parent27afd940ce6d91b1bf91f12f833ffce459919af6 (diff)
downloadgcc-5794b9f622dce668aa92ebabdf26abd0e799c665.zip
gcc-5794b9f622dce668aa92ebabdf26abd0e799c665.tar.gz
gcc-5794b9f622dce668aa92ebabdf26abd0e799c665.tar.bz2
PR c++/54293 - binding reference to member of temporary
* call.c (reference_binding): Fix binding to member of temporary. From-SVN: r240819
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog3
-rw-r--r--gcc/cp/call.c25
-rw-r--r--gcc/testsuite/g++.dg/init/ref19.C6
3 files changed, 21 insertions, 13 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index f8752a6..569d696 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,5 +1,8 @@
2016-10-05 Jason Merrill <jason@redhat.com>
+ PR c++/54293
+ * call.c (reference_binding): Fix binding to member of temporary.
+
* call.c (extend_ref_init_temps): Fix TARGET_EXPR handling.
* parser.c (cp_parser_skip_to_end_of_statement): Add missing break.
diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index c333418..dac1337 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -1539,15 +1539,20 @@ reference_binding (tree rto, tree rfrom, tree expr, bool c_cast_p, int flags,
gl_kind = clk_rvalueref;
}
else if (expr)
- {
- gl_kind = lvalue_kind (expr);
- if (gl_kind & clk_class)
- /* A class prvalue is not a glvalue. */
- gl_kind = clk_none;
- }
+ gl_kind = lvalue_kind (expr);
+ else if (CLASS_TYPE_P (from)
+ || TREE_CODE (from) == ARRAY_TYPE)
+ gl_kind = clk_class;
else
gl_kind = clk_none;
- is_lvalue = gl_kind && !(gl_kind & clk_rvalueref);
+
+ /* Don't allow a class prvalue when LOOKUP_NO_TEMP_BIND. */
+ if ((flags & LOOKUP_NO_TEMP_BIND)
+ && (gl_kind & clk_class))
+ gl_kind = clk_none;
+
+ /* Same mask as real_lvalue_p. */
+ is_lvalue = gl_kind && !(gl_kind & (clk_rvalueref|clk_class));
tfrom = from;
if ((gl_kind & clk_bitfield) != 0)
@@ -1569,11 +1574,7 @@ reference_binding (tree rto, tree rfrom, tree expr, bool c_cast_p, int flags,
[8.5.3/5 dcl.init.ref] is changed to also require direct bindings for
const and rvalue references to rvalues of compatible class type.
We should also do direct bindings for non-class xvalues. */
- if (related_p
- && (gl_kind
- || (!(flags & LOOKUP_NO_TEMP_BIND)
- && (CLASS_TYPE_P (from)
- || TREE_CODE (from) == ARRAY_TYPE))))
+ if (related_p && gl_kind)
{
/* [dcl.init.ref]
diff --git a/gcc/testsuite/g++.dg/init/ref19.C b/gcc/testsuite/g++.dg/init/ref19.C
index ed78c93..d583e93 100644
--- a/gcc/testsuite/g++.dg/init/ref19.C
+++ b/gcc/testsuite/g++.dg/init/ref19.C
@@ -11,7 +11,11 @@ struct A
int main()
{
- const int &r = A().i;
+ {
+ const int &r = A().i;
+ if (d != 0)
+ return 1;
+ }
if (d != 1)
return 1;
}