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:38:23 +0200 [thread overview]
Message-ID: <33a61119-b6be-45fc-299d-beec7c59e5ad@gjlay.de> (raw)
In-Reply-To: <CAH6eHdRos-4xfqFrK7XJS7uHe1e60mgK3sOz64DW6W2r-=QEnA@mail.gmail.com>
Am 04.05.23 um 12:12 schrieb Jonathan Wakely:
> 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.
Thank you. I came across that clause, but why is "token->lexer_" in
delete's argument a cast?
next prev parent reply other threads:[~2023-05-04 10:38 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
2023-05-04 10:38 ` Georg-Johann Lay [this message]
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=33a61119-b6be-45fc-299d-beec7c59e5ad@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).