https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94041

            Bug ID: 94041
           Summary: temporary object destructor called before the end of
                    the full-expression
           Product: gcc
           Version: 10.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: mawww at kakoune dot org
  Target Milestone: ---

Hello on current trunk, with no special options given, compiling the following
code:

struct Temp{ ~Temp(); };
struct A{ A(const Temp&) noexcept; };
struct B{ ~B(); };
struct Pair{ A a; B b; };

Temp make_temp() noexcept;
void foo(const Pair&) noexcept;

void bar(const Pair& p) noexcept
{
    foo({A(make_temp()), p.b});
}

generates the following assembly for the bar function:

bar(Pair const&):
        push    rbp
        mov     rbp, rsp
        sub     rsp, 32
        mov     QWORD PTR [rbp-24], rdi
        lea     rax, [rbp-1]
        mov     rdi, rax
        call    make_temp()
        lea     rdx, [rbp-1]
        lea     rax, [rbp-3]
        mov     rsi, rdx
        mov     rdi, rax
        call    A::A(Temp const&)
        lea     rax, [rbp-1]
        mov     rdi, rax
        call    Temp::~Temp() [complete object destructor]
        lea     rax, [rbp-3]
        mov     rdi, rax
        call    foo(Pair const&)
        lea     rax, [rbp-3]
        mov     rdi, rax
        call    Pair::~Pair() [complete object destructor]
        nop
        leave
        ret

Note the call to Temp::~Temp *before* the call to foo, which can lead to the A
object referring to a dangling Temp object when accessed in foo.

I believe that destructor call should only take place *after* calling foo, when
the full-expression actually ends.

This does not happen on gcc 9 and previous version, only on current trunk and
gcc-10 as provided in fedora rawhide.

Reply via email to