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: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

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