From 5794b9f622dce668aa92ebabdf26abd0e799c665 Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Wed, 5 Oct 2016 18:58:55 -0400 Subject: [PATCH] PR c++/54293 - binding reference to member of temporary * call.c (reference_binding): Fix binding to member of temporary. From-SVN: r240819 --- gcc/cp/ChangeLog | 3 +++ gcc/cp/call.c | 25 +++++++++++++------------ gcc/testsuite/g++.dg/init/ref19.C | 6 +++++- 3 files changed, 21 insertions(+), 13 deletions(-) diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index f8752a6911c..569d696546d 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,8 @@ 2016-10-05 Jason Merrill + 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 c33341813cf..dac1337cc49 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 ed78c939ba6..d583e939fdb 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; } -- 2.30.2