Created attachment 22649 [details] Reproducer program to run under gdb Problem Description: When a local object is created from a class with a virtual function and that object is also the retval for the function it is the local variable in, the debuginfo generated for the object indicates that it is located in a register, while in reality, its address is located in the register. Steps to Reproduce: $ cat > rep.cpp class Sequence { public: virtual void foo(void); }; Sequence getSequence() { Sequence data; return data; } $ g++ -g -c rep.cpp $ objdump -W rep.o | less ... <3><c4>: Abbrev Number: 13 (DW_TAG_variable) <c5> DW_AT_name : (indirect string, offset: 0x43): data <c9> DW_AT_decl_file : 1 <ca> DW_AT_decl_line : 8 <cb> DW_AT_type : <0x31> <cf> DW_AT_location : 1 byte block: 53 (DW_OP_reg3) ... Additional Information: Attached reproducer fullrep.cpp can be used to demonstrate this problem as seen in gdb. 1) Build fullrep.cpp: gcc -g fullrep.cpp 2) Run under gdb: [siddhesh@spoyarek gcc-foo]$ gdb -q ./a.out Reading symbols from /home/siddhesh/gcc-foo/a.out...done. (gdb) break getSequence Breakpoint 1 at 0x4007e0: file fullrep.cpp, line 14. (gdb) r Starting program: /home/siddhesh/gcc-foo/a.out Breakpoint 1, getSequence () at fullrep.cpp:14 14 Sequence data; (gdb) p data $1 = {_vptr.Sequence = 0x7fffffffdfd0, i = 4} (gdb) p &data Address requested for identifier "data" which is in register $rbx (gdb) p *((Sequence *)$rbx) $2 = {_vptr.Sequence = 0x7fffffffe0c0, i = 0} (gdb)
Created attachment 22660 [details] gcc46-pr46815.patch Ugh. So what happens is that we set DECL_VALUE_EXPR of the NRV optimized var to RESULT_DECL, but then in cp_genericize as it is addressable change the RESULT_DECL into DECL_BY_REFERENCE decl and convert_from_reference whenever it is seen in the stmts (but don't adjust the DECL_VALUE_EXPR of the var). Which means we end up using DW_OP_reg3 instead of DW_OP_breg3 0. Either we can do something like this patch, i.e. replace DECL_VALUE_EXPR during genericization, or we could do something similar, but faster by saving pointer to the NRV optimized VAR_DECL somewhere in the lang specific stuff for the FUNCTION_DECL, or, if we can be 100% sure by finalize_nrv time that non-addressable RESULT_DECL isn't ever going to turn into TREE_ADDRESSABLE RESULT_DECL, we could assume early what cp_genericize will do and set DECL_VALUE_EXPR in finalize_nrv to INDIRECT_REF of the RESULT_DECL (which would mean somewhat invalid tree until cp_genericize is run, but perhaps nothing would notice), or we could teach dwarf2out.c if it uses DECL_VALUE_EXPR and it points to DECL_BY_REFERENCE decl that it should add indirection automatically (but then, the question is what all will actually break by that). Jason, any preferences?
Let's go ahead with this patch.
Author: jakub Date: Wed Dec 15 17:50:34 2010 New Revision: 167865 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=167865 Log: PR debug/46815 * cp-gimplify.c (cp_genericize): When changing RESULT_DECL into invisible reference, change also DECL_VALUE_EXPR of NRV optimized variable. * g++.dg/guality/pr46815.C: New test. Added: trunk/gcc/testsuite/g++.dg/guality/pr46815.C Modified: trunk/gcc/cp/ChangeLog trunk/gcc/cp/cp-gimplify.c trunk/gcc/testsuite/ChangeLog
Fixed.