public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
From: "leni536 at gmail dot com" <gcc-bugzilla@gcc.gnu.org>
To: gcc-bugs@gcc.gnu.org
Subject: [Bug c++/98419] New: wrong code when destructor of local variable modifies returned object
Date: Tue, 22 Dec 2020 12:16:05 +0000	[thread overview]
Message-ID: <bug-98419-4@http.gcc.gnu.org/bugzilla/> (raw)

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

            Bug ID: 98419
           Summary: wrong code when destructor of local variable modifies
                    returned object
           Product: gcc
           Version: 10.2.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: leni536 at gmail dot com
  Target Milestone: ---

Version:
g++ (Compiler-Explorer-Build) 10.2.0

Command line options:
-std=c++17 -O2 -pedantic-errors


```
struct A {
    int i;
    A(int ** iptrptr): i(1) {
        *iptrptr = &i;
    }
};

struct B {
    int* iptr;
    B(): iptr(0) {}
    ~B() {
        *iptr = 2;
    }
};

A foo() {
    B b;
    return A(&b.iptr);
}
```

Observed behavior:
foo() returns an object with its `i` member having the value 1.

https://godbolt.org/z/Yhcjo9

Expected behavior:
foo() to return an object with its `i` member having the value 2.

The destruction of `b` is sequenced before the initialization of the returned
object. The constructor of A sets the int* contained in `b` to point within the
returned object (there is no temporary created with type A, C++17's mandatory
copy elision is assumed here). ~B() then sets the `i` member of the returned
object to 2.

Other observations:
With command line options `-std=c++17 -O0 -pedantic-errors -fsanitize=address`
~B() tramples the stack:

https://godbolt.org/z/M5ETa9

When A has a user-defined copy-constructor or destructor then I get the
expected behavior:

https://godbolt.org/z/osqbfz
https://godbolt.org/z/ozzPaf

Presumably when the returned type is trivially copyable then the copy isn't
elided, with the assumption that it's not observable. In C++17 the copy elision
is mandatory, and it is observable even for trivially copyable types, as shown
in this example.

             reply	other threads:[~2020-12-22 12:16 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-12-22 12:16 leni536 at gmail dot com [this message]
2020-12-22 12:36 ` [Bug c++/98419] " marxin at gcc dot gnu.org
2020-12-22 21:05 ` leni536 at gmail dot com
2020-12-23 10:59 ` marxin at gcc dot gnu.org

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=bug-98419-4@http.gcc.gnu.org/bugzilla/ \
    --to=gcc-bugzilla@gcc.gnu.org \
    --cc=gcc-bugs@gcc.gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).