From: Georg-Johann Lay <avr@gjlay.de>
To: Jonathan Wakely <jwakely.gcc@gmail.com>
Cc: gcc-help@gcc.gnu.org
Subject: Re: g++ problem with order of evaluation of arguments of delete.
Date: Thu, 4 May 2023 12:54:03 +0200 [thread overview]
Message-ID: <77bfe681-7500-f525-9f4a-c2f6f0112598@gjlay.de> (raw)
In-Reply-To: <CAH6eHdTwWCe19=Gr+Co2qQDwz4D+aoGcAujHQOK1SkyKdShsNw@mail.gmail.com>
Am 04.05.23 um 12:25 schrieb Jonathan Wakely:
> On Thu, 4 May 2023 at 11:12, Jonathan Wakely <jwakely.gcc@gmail.com> wrote:
>>
>> On Thu, 4 May 2023 at 11:06, Jonathan Wakely <jwakely.gcc@gmail.com> wrote:
>>>
>>> On Thu, 4 May 2023 at 10:46, Georg-Johann Lay <avr@gjlay.de> wrote:
>>>>
>>>> Given the following C++ code:
>>>>
>>>> struct Lexer;
>>>>
>>>> struct Token
>>>> {
>>>> Lexer* const lexer_;
>>>> Token (Lexer *l) : lexer_(l) {}
>>>> ~Token() = default;
>>>>
>>>> Token() = delete;
>>>> Token (const Token&) = delete;
>>>> Token (Token&&) = delete;
>>>> void operator= (const Token&) = delete;
>>>> void operator= (Token&&) = delete;
>>>> };
>>>>
>>>> struct Lexer
>>>> {
>>>> Token *token_;
>>>> Lexer() = default;
>>>> ~Lexer() { delete token_; }
>>>>
>>>> Lexer (const Lexer&) = delete;
>>>> Lexer (Lexer&&) = delete;
>>>> void operator= (const Lexer&) = delete;
>>>> void operator= (Lexer&&) = delete;
>>>> };
>>>>
>>>> int main()
>>>> {
>>>> Lexer *lexer = new Lexer();
>>>> Token *token = new Token (lexer);
>>>> lexer->token_ = token;
>>>> delete token->lexer_;
>>>> // delete lexer; // is OK
>>>> }
>>>>
>>>> When I compile this with g++ v11.3 (same with g++ from master from
>>>> 2023-04-20) and run
>>>>
>>>> $ g++ main-3.cpp -Os -W -Wall -Wextra -dumpbase "" -save-temps -dp &&
>>>> ./a.out
>>>>
>>>> Segmentation fault (core dumped)
>>>>
>>>> The assembly shows that the generated code does two calls to "delete"
>>>> but just one call to "new", so it's clear something is going wrong.
>>>>
>>>> As far as I understand, the "delete token_" in ~Lexer is a sequence
>>>> point, so that dereferencing token in "delete->lexer_" must be sequenced
>>>> before calling ~Token ?
>>>>
>>>> Segmentation fault also occurs with -O0, but goes away when removing the
>>>> "const" in "Lexer* const lexer_;".
>>>>
>>>> My question: Is this a GCC problem, or a problem with the code and
>>>> sequence points?
>>>
>>> It's definitely a GCC bug.
>>>
>>> The code is compiled to something like:
>>>
>>> token->lexer_->~Lexer();
>>> operator delete(token->lexer_);
>>>
>>> But that means that we evaluate 'token' twice, even though it's been
>>> invalidated by the destructor. It should be compiled to something more
>>> like:
>>>
>>> auto* p = token->lexer_;
>>> p->~Lexer();
>>> operator delete(p);
>>
>> The C++ standard is clear, see [expr.delete] p4:
>>
>> "The cast-expression in a delete-expression shall be evaluated exactly once."
>>
>> That wording has been present since C++98.
>>
>> Please file a bug.
>
> The bug was already present in gcc 4.1.0, I didn't check anything
> older than r0-71179-gc6ff1944941b0c aka r105000
Filed as https://gcc.gnu.org/PR109731
next prev parent reply other threads:[~2023-05-04 10:54 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-05-04 9:45 Georg-Johann Lay
2023-05-04 9:58 ` LIU Hao
2023-05-04 10:02 ` Jonathan Wakely
2023-05-04 10:00 ` Marc Glisse
2023-05-04 10:06 ` Jonathan Wakely
2023-05-04 10:12 ` Jonathan Wakely
2023-05-04 10:25 ` Jonathan Wakely
2023-05-04 10:54 ` Georg-Johann Lay [this message]
2023-05-04 10:38 ` Georg-Johann Lay
2023-05-04 10:44 ` Jonathan Wakely
2023-05-10 1:31 ` LIU Hao
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=77bfe681-7500-f525-9f4a-c2f6f0112598@gjlay.de \
--to=avr@gjlay.de \
--cc=gcc-help@gcc.gnu.org \
--cc=jwakely.gcc@gmail.com \
/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).