public inbox for gcc-help@gcc.gnu.org
 help / color / mirror / Atom feed
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?


  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).